mirror of
https://code.forgejo.org/actions/cascading-pr.git
synced 2025-07-22 07:18:26 +02:00
Merge pull request 'fix: loop over the open pull requests to get an exact title match' (#37) from earl-warren/cascading-pr:wip-search into main
Some checks failed
integration / integration (push) Has been cancelled
Some checks failed
integration / integration (push) Has been cancelled
Reviewed-on: https://code.forgejo.org/actions/cascading-pr/pulls/37
This commit is contained in:
commit
27e6cc5755
5 changed files with 149 additions and 134 deletions
|
@ -14,19 +14,22 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- id: forgejo
|
- id: forgejo
|
||||||
uses: https://code.forgejo.org/actions/setup-forgejo@v1.0.1
|
uses: https://code.forgejo.org/actions/setup-forgejo@v3.0.1
|
||||||
with:
|
with:
|
||||||
user: root
|
user: root
|
||||||
password: admin1234
|
password: admin1234
|
||||||
image: codeberg.org/forgejo/forgejo
|
image: codeberg.org/forgejo/forgejo
|
||||||
image-version: 1.21
|
image-version: 11
|
||||||
lxc-ip-prefix: 10.1.15
|
lxc-ip-prefix: 10.1.15
|
||||||
|
|
||||||
- name: tests cascading-pr
|
- name: tests cascading-pr
|
||||||
run: |
|
run: |
|
||||||
|
set -x
|
||||||
|
export PATH=$(pwd):$PATH
|
||||||
runner_config=/tmp/runner-config.yaml
|
runner_config=/tmp/runner-config.yaml
|
||||||
sed -e 's|file: .runner|file: ${{ steps.forgejo.outputs.runner-file }}|' < tests/runner-config.yaml > $runner_config
|
sed -e 's|file: .runner|file: ${{ steps.forgejo.outputs.runner-file }}|' < tests/runner-config.yaml > $runner_config
|
||||||
FORGEJO_RUNNER_CONFIG=$runner_config forgejo-runner.sh reload
|
DIR=$(dirname ${{ steps.forgejo.outputs.runner-file }})
|
||||||
|
DIR=$DIR FORGEJO_RUNNER_CONFIG=$runner_config forgejo-runner.sh reload
|
||||||
tests/run.sh --verbose --host_port ${{ steps.forgejo.outputs.host-port }} --url ${{ steps.forgejo.outputs.url }} --token ${{ steps.forgejo.outputs.token }}
|
tests/run.sh --verbose --host_port ${{ steps.forgejo.outputs.host-port }} --url ${{ steps.forgejo.outputs.url }} --token ${{ steps.forgejo.outputs.token }}
|
||||||
|
|
||||||
- name: full logs
|
- name: full logs
|
||||||
|
@ -34,4 +37,4 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sed -e 's/^/[RUNNER LOGS] /' ${{ steps.forgejo.outputs.runner-logs }}
|
sed -e 's/^/[RUNNER LOGS] /' ${{ steps.forgejo.outputs.runner-logs }}
|
||||||
docker logs forgejo | sed -e 's/^/[FORGEJO LOGS]/'
|
docker logs forgejo | sed -e 's/^/[FORGEJO LOGS]/'
|
||||||
sleep 5 # hack to avoid mixing outputs in Forgejo v1.21
|
sleep 5 # hack to avoid mixing outputs in Forgejo v12.0
|
||||||
|
|
|
@ -179,12 +179,13 @@ The test environment consists of the following (all users password is admin1234)
|
||||||
git clone https://code.forgejo.org/actions/setup-forgejo
|
git clone https://code.forgejo.org/actions/setup-forgejo
|
||||||
export PATH=$(pwd)/setup-forgejo:$PATH
|
export PATH=$(pwd)/setup-forgejo:$PATH
|
||||||
git clone https://code.forgejo.org/actions/cascading-pr
|
git clone https://code.forgejo.org/actions/cascading-pr
|
||||||
|
export PATH=$(pwd)/cascading-pr:$PATH
|
||||||
cd cascading-pr
|
cd cascading-pr
|
||||||
export DIR=/tmp/forgejo-for-cascading-pr
|
export DIR=/tmp/forgejo-for-cascading-pr
|
||||||
forgejo-curl.sh logout
|
forgejo-curl.sh logout
|
||||||
forgejo-runner.sh teardown
|
forgejo-runner.sh teardown
|
||||||
forgejo-binary.sh teardown
|
forgejo-binary.sh teardown
|
||||||
forgejo-binary.sh setup root admin1234 https://codeberg.org/forgejo/forgejo/releases/download/v1.21.3-0/forgejo-1.21.3-0-linux-amd64
|
forgejo-binary.sh setup root admin1234 https://codeberg.org/forgejo/forgejo/releases/download/v11.0.3/forgejo-11.0.3-linux-amd64
|
||||||
FORGEJO_RUNNER_CONFIG=$(pwd)/tests/runner-config.yaml forgejo-runner.sh setup
|
FORGEJO_RUNNER_CONFIG=$(pwd)/tests/runner-config.yaml forgejo-runner.sh setup
|
||||||
url=$(cat $DIR/forgejo-url)
|
url=$(cat $DIR/forgejo-url)
|
||||||
firefox $url
|
firefox $url
|
||||||
|
@ -207,7 +208,7 @@ The test for a successful run of the cascading-pr action consists of:
|
||||||
|
|
||||||
Following the steps below recreate the same environment as the
|
Following the steps below recreate the same environment as the
|
||||||
integration workflow locally. It is helpful for forensic analysis when
|
integration workflow locally. It is helpful for forensic analysis when
|
||||||
something does not run as expected and the error displayed are unclear.
|
something does not run as expected and the errors displayed are unclear.
|
||||||
|
|
||||||
To help with the development loop all steps are idempotent and
|
To help with the development loop all steps are idempotent and
|
||||||
running `tests/run.sh --debug` multiple times must succeed.
|
running `tests/run.sh --debug` multiple times must succeed.
|
||||||
|
|
|
@ -14,7 +14,7 @@ function repo_login() {
|
||||||
local direction="$1"
|
local direction="$1"
|
||||||
local repo=${options[${direction}_repo]}
|
local repo=${options[${direction}_repo]}
|
||||||
(
|
(
|
||||||
export DOT=$TMPDIR/$repo
|
export DOT_FORGEJO_CURL=$TMPDIR/$repo
|
||||||
forgejo-curl.sh logout
|
forgejo-curl.sh logout
|
||||||
forgejo-curl.sh --token "${options[${direction}_token]}" login "${options[${direction}_url]}"
|
forgejo-curl.sh --token "${options[${direction}_token]}" login "${options[${direction}_url]}"
|
||||||
)
|
)
|
||||||
|
@ -23,7 +23,7 @@ function repo_login() {
|
||||||
function repo_curl() {
|
function repo_curl() {
|
||||||
local repo=$1
|
local repo=$1
|
||||||
shift
|
shift
|
||||||
DOT=$TMPDIR/$repo forgejo-curl.sh "$@"
|
DOT_FORGEJO_CURL=$TMPDIR/$repo forgejo-curl.sh "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
function default_branch() {
|
function default_branch() {
|
||||||
|
@ -132,7 +132,19 @@ function pr_get_origin() {
|
||||||
|
|
||||||
function pr_get_destination() {
|
function pr_get_destination() {
|
||||||
local title=$(pr_destination_title)
|
local title=$(pr_destination_title)
|
||||||
repo_curl ${options[destination_repo]} api --get --data state=open --data type=pulls --data-urlencode q="$title" ${options[destination_api]}/issues | jq --raw-output .[0] >$TMPDIR/destination-pr.json
|
local page=1
|
||||||
|
touch $TMPDIR/destination-pr.json
|
||||||
|
while true; do
|
||||||
|
repo_curl ${options[destination_repo]} api --get --data page=$page --data state=open --data type=pulls ${options[destination_api]}/issues >$TMPDIR/destination-prs.json
|
||||||
|
if test "$(jq length <$TMPDIR/destination-prs.json)" = 0; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
jq --argjson title "\"$title\"" '.[] | select(.title == $title)' <$TMPDIR/destination-prs.json >$TMPDIR/destination-pr.json
|
||||||
|
if test -s $TMPDIR/destination-pr.json; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
page=$(expr $page + 1)
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function pr_get() {
|
function pr_get() {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
VERSION=1.0.0
|
VERSION=1.0.1
|
||||||
SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
VERBOSE=false
|
VERBOSE=false
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
: ${EXIT_ON_ERROR:=true}
|
: ${EXIT_ON_ERROR:=true}
|
||||||
: ${TOKEN_NAME:=forgejo-curl}
|
: ${TOKEN_NAME:=forgejo-curl}
|
||||||
: ${DOT:=$HOME/.forgejo-curl}
|
: ${DOT_FORGEJO_CURL:=$HOME/.forgejo-curl}
|
||||||
|
: ${DOT:=$DOT_FORGEJO_CURL}
|
||||||
|
|
||||||
function debug() {
|
function debug() {
|
||||||
DEBUG=true
|
DEBUG=true
|
||||||
|
@ -28,7 +29,7 @@ function log_error() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function log_verbose() {
|
function log_verbose() {
|
||||||
if $VERBOSE; then
|
if $VERBOSE ; then
|
||||||
log "$@"
|
log "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -39,7 +40,7 @@ function log_info() {
|
||||||
|
|
||||||
function fatal_error() {
|
function fatal_error() {
|
||||||
log_error "$@"
|
log_error "$@"
|
||||||
if $EXIT_ON_ERROR; then
|
if $EXIT_ON_ERROR ; then
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
|
@ -47,12 +48,12 @@ function fatal_error() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function dot_ensure() {
|
function dot_ensure() {
|
||||||
mkdir -p $DOT
|
mkdir -p $DOT_FORGEJO_CURL
|
||||||
}
|
}
|
||||||
|
|
||||||
HEADER_JSON='-H Content-Type:application/json'
|
HEADER_JSON='-H Content-Type:application/json'
|
||||||
HEADER_TOKEN="-H @$DOT/header-token"
|
HEADER_TOKEN="-H @$DOT_FORGEJO_CURL/header-token"
|
||||||
HEADER_CSRF="-H @$DOT/header-csrf"
|
HEADER_CSRF="-H @$DOT_FORGEJO_CURL/header-csrf"
|
||||||
|
|
||||||
function api() {
|
function api() {
|
||||||
client $HEADER_TOKEN "$@"
|
client $HEADER_TOKEN "$@"
|
||||||
|
@ -66,43 +67,40 @@ function login_api() {
|
||||||
local user="$1" password="$2" token="$3" scopes="${4:-[\"all\"]}" url="$5"
|
local user="$1" password="$2" token="$3" scopes="${4:-[\"all\"]}" url="$5"
|
||||||
|
|
||||||
dot_ensure
|
dot_ensure
|
||||||
if test -s $DOT/token; then
|
if test -s $DOT_FORGEJO_CURL/token ; then
|
||||||
log_info "already logged in, ignored"
|
log_info "already logged in, ignored"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "$token"; then
|
if test -z "$token" ; then
|
||||||
log_verbose curl -sS -X DELETE --user "${user}:${password}" "${url}/api/v1/users/$user/tokens/${TOKEN_NAME}" -o /dev/null -w "%{http_code}"
|
log_verbose curl -sS -X DELETE --user "${user}:${password}" "${url}/api/v1/users/$user/tokens/${TOKEN_NAME}" -o /dev/null -w "%{http_code}"
|
||||||
local basic="${user:-unknown}:${password:-unknown}"
|
local basic="${user:-unknown}:${password:-unknown}"
|
||||||
local status=$(curl -sS -X DELETE --user "${basic}" "${url}/api/v1/users/$user/tokens/${TOKEN_NAME}" -o /dev/null -w "%{http_code}")
|
local status=$(curl -sS -X DELETE --user "${basic}" "${url}/api/v1/users/$user/tokens/${TOKEN_NAME}" -o /dev/null -w "%{http_code}")
|
||||||
if test "${status}" != 404 -a "${status}" != 204; then
|
if test "${status}" != 404 -a "${status}" != 204 ; then
|
||||||
fatal_error permission denied, the user or password are probably incorrect, try again with --verbose
|
fatal_error permission denied, the user or password are probably incorrect, try again with --verbose
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
token=$(client $HEADER_JSON --user "${basic}" --data-raw '{"name":"'${TOKEN_NAME}'","scopes":'${scopes}'}' "${url}/api/v1/users/${user}/tokens" | jq --raw-output .sha1)
|
token=$(client $HEADER_JSON --user "${basic}" --data-raw '{"name":"'${TOKEN_NAME}'","scopes":'${scopes}'}' "${url}/api/v1/users/${user}/tokens" | jq --raw-output .sha1)
|
||||||
fi
|
fi
|
||||||
if [[ "$token" =~ ^@ ]]; then
|
if [[ "$token" =~ ^@ ]] ; then
|
||||||
cp "${token##@}" $DOT/token
|
cp "${token##@}" $DOT_FORGEJO_CURL/token
|
||||||
else
|
else
|
||||||
echo "$token" >$DOT/token
|
echo "$token" > $DOT_FORGEJO_CURL/token
|
||||||
fi
|
fi
|
||||||
(
|
( echo -n "Authorization: token " ; cat $DOT_FORGEJO_CURL/token ) > $DOT_FORGEJO_CURL/header-token
|
||||||
echo -n "Authorization: token "
|
|
||||||
cat $DOT/token
|
|
||||||
) >$DOT/header-token
|
|
||||||
#
|
#
|
||||||
# Verify it works
|
# Verify the token works
|
||||||
#
|
#
|
||||||
local status=$(api -w "%{http_code}" -o /dev/null "${url}/api/v1/user")
|
local status=$(api -w "%{http_code}" -o /dev/null "${url}/api/v1/user")
|
||||||
if test "${status}" != 200; then
|
if test "${status}" != 200 ; then
|
||||||
fatal_error "${url}/api/v1/user returns status code '${status}', the token is invalid, $0 logout and login again"
|
fatal_error "${url}/api/v1/user returns status code '${status}', the token is invalid, $0 logout and login again"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function client() {
|
function client() {
|
||||||
log_verbose curl --cookie $DOT/cookies -f -sS "$@"
|
log_verbose curl --cookie $DOT_FORGEJO_CURL/cookies -f -sS "$@"
|
||||||
if ! curl --cookie $DOT/cookies -f -sS "$@"; then
|
if ! curl --cookie $DOT_FORGEJO_CURL/cookies -f -sS "$@" ; then
|
||||||
fatal_error
|
fatal_error
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -112,9 +110,9 @@ function web() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function client_update_cookies() {
|
function client_update_cookies() {
|
||||||
log_verbose curl --cookie-jar $DOT/cookies --cookie $DOT/cookies -w "%{http_code}" -f -sS "$@"
|
log_verbose curl --cookie-jar $DOT_FORGEJO_CURL/cookies --cookie $DOT_FORGEJO_CURL/cookies -w "%{http_code}" -f -sS "$@"
|
||||||
local status=$(curl --cookie-jar $DOT/cookies --cookie $DOT/cookies -w "%{http_code}" -f -sS "$@")
|
local status=$(curl --cookie-jar $DOT_FORGEJO_CURL/cookies --cookie $DOT_FORGEJO_CURL/cookies -w "%{http_code}" -f -sS "$@")
|
||||||
if ! test "${status}" = 200 -o "${status}" = 303; then
|
if ! test "${status}" = 200 -o "${status}" = 303 ; then
|
||||||
fatal_error
|
fatal_error
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -122,7 +120,7 @@ function client_update_cookies() {
|
||||||
function login_client() {
|
function login_client() {
|
||||||
local user="$1" password="$2" url="$3"
|
local user="$1" password="$2" url="$3"
|
||||||
|
|
||||||
if test -z "$password"; then
|
if test -z "$password" ; then
|
||||||
log_verbose "no password, web will not be authenticated"
|
log_verbose "no password, web will not be authenticated"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
@ -135,21 +133,21 @@ function login_client() {
|
||||||
#
|
#
|
||||||
# The login stores a cookie
|
# The login stores a cookie
|
||||||
#
|
#
|
||||||
client_update_cookies -X POST --data "user_name=${user}" --data "password=${password}" "${url}/user/login" -o $DOT/login.html
|
client_update_cookies -X POST --data "user_name=${user}" --data "password=${password}" "${url}/user/login" -o $DOT_FORGEJO_CURL/login.html
|
||||||
#
|
#
|
||||||
# Get the CSRF for reuse by other requests
|
# Get the CSRF for reuse by other requests
|
||||||
#
|
#
|
||||||
client_update_cookies -o /dev/null "${url}/user/login"
|
client_update_cookies -o /dev/null "${url}/user/login"
|
||||||
local csrf=$(sed -n -e '/csrf/s/.*csrf\t//p' $DOT/cookies)
|
local csrf=$(sed -n -e '/csrf/s/.*csrf\t//p' $DOT_FORGEJO_CURL/cookies)
|
||||||
echo "X-Csrf-Token: $csrf" >$DOT/header-csrf
|
echo "X-Csrf-Token: $csrf" > $DOT_FORGEJO_CURL/header-csrf
|
||||||
#
|
#
|
||||||
# Verify it works
|
# Verify it works
|
||||||
#
|
#
|
||||||
local status=$(web -o /dev/null -w "%{http_code}" "${url}/user/settings")
|
local status=$(web -o /dev/null -w "%{http_code}" "${url}/user/settings")
|
||||||
if test "${status}" != 200; then
|
if test "${status}" != 200 ; then
|
||||||
grep -C 1 flash-error $DOT/login.html
|
grep -C 1 flash-error $DOT_FORGEJO_CURL/login.html
|
||||||
if ${DEBUG}; then
|
if ${DEBUG} ; then
|
||||||
cat $DOT/login.html
|
cat $DOT_FORGEJO_CURL/login.html
|
||||||
fi
|
fi
|
||||||
fatal_error login failed, the user or password are probably incorrect, try again with --verbose
|
fatal_error login failed, the user or password are probably incorrect, try again with --verbose
|
||||||
fi
|
fi
|
||||||
|
@ -162,12 +160,13 @@ function login() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
rm -f $DOT/*
|
rm -f $DOT_FORGEJO_CURL/*
|
||||||
if test -d $DOT; then
|
if test -d $DOT_FORGEJO_CURL ; then
|
||||||
rmdir $DOT
|
rmdir $DOT_FORGEJO_CURL
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function usage() {
|
function usage() {
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
forgejo-curl.sh - thin curl wrapper that helps with Forgejo authentication
|
forgejo-curl.sh - thin curl wrapper that helps with Forgejo authentication
|
||||||
|
@ -187,9 +186,9 @@ LOGIN AND TOKEN
|
||||||
The web endpoints that require authentication will be given a cookie
|
The web endpoints that require authentication will be given a cookie
|
||||||
and CSRF token created using the the --user and --password credentials
|
and CSRF token created using the the --user and --password credentials
|
||||||
|
|
||||||
On a successful login the credentials are stored in the $DOT
|
On a successful login the credentials are stored in the $DOT_FORGEJO_CURL
|
||||||
directory to be used by the web, api, api_json commands. The logout
|
directory to be used by the web, api, api_json commands. The logout
|
||||||
command removes the $DOT directory.
|
command removes the $DOT_FORGEJO_CURL directory.
|
||||||
|
|
||||||
If the argument of --token starts with @, it is used as a filename
|
If the argument of --token starts with @, it is used as a filename
|
||||||
from which the token will be read.
|
from which the token will be read.
|
||||||
|
@ -329,7 +328,7 @@ function main() {
|
||||||
echo "forgejo-curl.sh version $VERSION"
|
echo "forgejo-curl.sh version $VERSION"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
--help | *)
|
--help|*)
|
||||||
usage
|
usage
|
||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -12,13 +12,13 @@ source $SELF_DIR/../cascading-pr-lib.sh
|
||||||
|
|
||||||
function push_self() {
|
function push_self() {
|
||||||
log_verbose "push cascading-pr action to user1/cascading-pr"
|
log_verbose "push cascading-pr action to user1/cascading-pr"
|
||||||
forgejo-test-helper.sh push_self_action http://user1:admin1234@${options[host_port]} user1 cascading-pr vTest
|
forgejo-test-helper.sh push_self_action http://placeholder:${options[token]}@${options[host_port]} user1 cascading-pr vTest
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_login() {
|
function user_login() {
|
||||||
local username=$1
|
local username=$1
|
||||||
(
|
(
|
||||||
export DOT=$TMPDIR/$username
|
export DOT_FORGEJO_CURL=$TMPDIR/$username
|
||||||
forgejo-curl.sh logout
|
forgejo-curl.sh logout
|
||||||
forgejo-curl.sh --user $username --password "${options[password]}" login ${options[url]}
|
forgejo-curl.sh --user $username --password "${options[password]}" login ${options[url]}
|
||||||
)
|
)
|
||||||
|
@ -27,13 +27,13 @@ function user_login() {
|
||||||
function user_curl() {
|
function user_curl() {
|
||||||
local username=$1
|
local username=$1
|
||||||
shift
|
shift
|
||||||
DOT=$TMPDIR/$username forgejo-curl.sh "$@"
|
DOT_FORGEJO_CURL=$TMPDIR/$username forgejo-curl.sh "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_token() {
|
function user_token() {
|
||||||
local username=$1 name=$2
|
local username=$1 name=$2
|
||||||
|
|
||||||
curl -sS -f -H Content-Type:application/json --user "$username:${options[password]}" --data '{"name":"'$name'","scopes":["write:repository","write:issue","read:organization","read:user"]}' ${options[url]}/api/v1/users/$username/tokens | jq --raw-output .sha1 | tee $TMPDIR/$username/repo-token
|
curl --fail -sS -f -H Content-Type:application/json --user "$username:${options[password]}" --data '{"name":"'$name'","scopes":["write:repository","write:issue","read:organization","read:user"]}' ${options[url]}/api/v1/users/$username/tokens | jq --raw-output .sha1 | tee $TMPDIR/$username/repo-token
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_secret() {
|
function user_secret() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue