Merge pull request 'example-push-cancel: test that pushing to a branch cancels workflows' (#57) from earl-warren/setup-forgejo:wip-example-cancel into main

Reviewed-on: https://code.forgejo.org/actions/setup-forgejo/pulls/57
Reviewed-by: dachary <dachary@noreply.code.forgejo.org>
This commit is contained in:
earl-warren 2023-10-07 22:28:02 +00:00
commit 37e5096b0d
11 changed files with 123 additions and 52 deletions

View file

@ -9,10 +9,10 @@ jobs:
- version: "1.21.0-2-rc0" - version: "1.21.0-2-rc0"
image: codeberg.org/forgejo-experimental/forgejo image: codeberg.org/forgejo-experimental/forgejo
# keep "cron" last otherwise it will linger and pollute the following runs # keep "cron" last otherwise it will linger and pollute the following runs
tests: "${{ vars.V121_TESTS || 'echo artifacts service checkout pull-request container expression local-action docker-action if if-fail cron' }}" tests: "${{ vars.V1_21_TESTS || 'echo push-cancel artifacts service checkout pull-request container expression local-action docker-action if if-fail cron' }}"
- version: "1.20" - version: "1.20"
image: codeberg.org/forgejo/forgejo image: codeberg.org/forgejo/forgejo
tests: "${{ vars.V120_TESTS || 'echo checkout service container expression local-action docker-action if if-fail' }}" tests: "${{ vars.V1_20_TESTS || 'echo checkout service container expression local-action docker-action if if-fail' }}"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- if: matrix.info.tests != 'none' - if: matrix.info.tests != 'none'
@ -31,10 +31,11 @@ jobs:
# #
forgejo-runner.sh setup forgejo-runner.sh setup
export FORGEJO_RUNNER_LOGS=forgejo-runner.log export FORGEJO_RUNNER_LOGS=forgejo-runner.log
url=http://root:admin1234@$(cat forgejo-ip):3000
token=$(cat forgejo-token)
echo "============================ demo ===================" echo "============================ demo ==================="
./forgejo-test-helper.sh run_workflow testdata/demo http://root:admin1234@$(cat forgejo-ip):3000 root demo setup-forgejo $(cat forgejo-token) > /tmp/output forgejo-test-helper.sh run_workflow testdata/demo $url root demo setup-forgejo $token
grep '^sha=' /tmp/output
function run() { function run() {
local example=$1 local example=$1
@ -51,7 +52,7 @@ jobs:
echo "============================ RUN example-$example ===================" echo "============================ RUN example-$example ==================="
bash -ex $EXAMPLE_DIR/run.sh || return 1 bash -ex $EXAMPLE_DIR/run.sh || return 1
else else
forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token) || return 1 forgejo-test-helper.sh run_workflow testdata/example-$example $url root example-$example setup-forgejo $token || return 1
fi fi
if test -f $EXAMPLE_DIR/teardown.sh ; then if test -f $EXAMPLE_DIR/teardown.sh ; then

View file

@ -20,8 +20,7 @@ The forgejo-test-helper.sh script is available to help test and debug actions.
`testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`. `testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`.
* `forgejo-test-helper.sh push testrepo $forgejo root testrepo` * `forgejo-test-helper.sh push testrepo $forgejo root testrepo`
Creates the repository `$forgejo/root/testrepo` and populates it with the Creates the repository `$forgejo/root/testrepo` and populates it with the
content of the `testrepo` directory. The SHA of the tip of the repository content of the `testrepo` directory.
is in the output, on a line starting with `sha=`.
* `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1` * `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1`
Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`. Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`.
`export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh` `export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh`
@ -87,9 +86,13 @@ jobs:
## Hacking ## Hacking
* Update the README from the action file with https://github.com/npalm/action-docs `action-docs --update-readme` ### Documentation
To manually run and debug workflows from `testdata/example-*`, from Update the README from the action file with https://github.com/npalm/action-docs `action-docs --update-readme`
### Local testing
To run and debug workflows from `testdata/example-*`, from
the root of the source directory, with docker and forgejo-curl.sh the root of the source directory, with docker and forgejo-curl.sh
installed, mimic what `.forgejo/workflows/integration.yml` does. There installed, mimic what `.forgejo/workflows/integration.yml` does. There
may be some manual tweaking (such as creating temporary directories) may be some manual tweaking (such as creating temporary directories)
@ -106,3 +109,14 @@ because the tests run as root, but they do not need to run as root.
* `forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token)` * `forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token)`
* `forgejo-runner.sh teardown` * `forgejo-runner.sh teardown`
* `forgejo.sh teardown` * `forgejo.sh teardown`
### Remote testing
To reduce the runtime the following variables can be set to control
the number of cases run by the
[integration](.forgejo/workflows/integration.yml) tests. If set to
**none** they are not run at all for that version of Forgejo. If
it does not exist, all tests are run.
* `V1_21_TESTS`
* `V1_20_TESTS`

View file

@ -19,8 +19,7 @@ description: |
`testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`. `testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`.
* `forgejo-test-helper.sh push testrepo $forgejo root testrepo` * `forgejo-test-helper.sh push testrepo $forgejo root testrepo`
Creates the repository `$forgejo/root/testrepo` and populates it with the Creates the repository `$forgejo/root/testrepo` and populates it with the
content of the `testrepo` directory. The SHA of the tip of the repository content of the `testrepo` directory.
is in the output, on a line starting with `sha=`.
* `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1` * `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1`
Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`. Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`.
`export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh` `export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh`

View file

@ -5,8 +5,8 @@ set -ex
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
: ${LOOPS:=40} : ${LOOPS:=80}
: ${LOOP_DELAY:=10} : ${LOOP_DELAY:=5}
DIR=$(mktemp -d) DIR=$(mktemp -d)
trap "rm -fr $DIR" EXIT trap "rm -fr $DIR" EXIT
@ -44,6 +44,15 @@ function build_runner() {
forgejo-runner --version forgejo-runner --version
} }
function branch_tip() {
local url="$1"
local repo="$2"
local branch="$3"
forgejo.sh retry forgejo-curl.sh api_json $url/api/v1/repos/$repo/branches/$branch >& /dev/null
forgejo-curl.sh api_json $url/api/v1/repos/$repo/branches/$branch | jq --raw-output .commit.id
}
function get_status() { function get_status() {
local url="$1" local url="$1"
local repo="$2" local repo="$2"
@ -56,25 +65,48 @@ function check_status() {
local url="$1" local url="$1"
local repo="$2" local repo="$2"
local sha="$3" local sha="$3"
local expected_status="$4"
local expected_description="$5"
local state=$(get_status $url $repo $sha | jq --raw-output .state) get_status $url $repo $sha > /tmp/status.json
echo $state local status="$(jq --raw-output .state < /tmp/status.json)"
test "$state" != "" -a "$state" != "pending" -a "$state" != "running" -a "$state" != "null" local description="$(jq --raw-output .statuses[0].description < /tmp/status.json)"
if test "$status" = "$expected_status" && test -z "$expected_description" -o "$description" = "$expected_description"; then
echo OK
elif test "$status" = "failure" -o "$status" = "success"; then
echo NOK
else
echo RETRY
fi
} }
function wait_success() { function wait_success() {
local url="$1" wait_status success "$@"
local repo="$2" }
local sha="$3"
function wait_failure() {
wait_status failure "$@"
}
function wait_running() {
wait_status pending "$@" "Has started running"
}
function wait_status() {
local status="$1"
local url="$2"
local repo="$3"
local sha="$4"
local description="$5"
for i in $(seq $LOOPS); do for i in $(seq $LOOPS); do
if check_status "$url" "$repo" "$sha"; then if test $(check_status "$url" "$repo" "$sha" "$status" "$description") != RETRY ; then
break break
fi fi
test "$FORGEJO_RUNNER_LOGS" && tail $FORGEJO_RUNNER_LOGS test "$FORGEJO_RUNNER_LOGS" && tail $FORGEJO_RUNNER_LOGS
sleep $LOOP_DELAY sleep $LOOP_DELAY
done done
if ! test "$(check_status "$url" "$repo" "$sha")" = "success" ; then if test $(check_status "$url" "$repo" "$sha" "$status" "$description") != "OK" ; then
get_status $url $repo $sha | jq .statuses get_status $url $repo $sha | jq .statuses
test "$FORGEJO_RUNNER_LOGS" && cat $FORGEJO_RUNNER_LOGS test "$FORGEJO_RUNNER_LOGS" && cat $FORGEJO_RUNNER_LOGS
return 1 return 1
@ -111,7 +143,6 @@ function push() {
git push --force -u origin main git push --force -u origin main
sha=$(git rev-parse HEAD) sha=$(git rev-parse HEAD)
echo $sha > SHA echo $sha > SHA
echo sha=$sha
) )
} }

View file

@ -1,8 +1,10 @@
on: [push] on: [push]
jobs: jobs:
ls: v3:
runs-on: docker runs-on: docker
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- run: | v4:
ls ${{ github.workspace }} runs-on: docker
steps:
- uses: actions/checkout@v4

View file

@ -1,8 +0,0 @@
on: [push]
jobs:
ls:
runs-on: docker
steps:
- uses: actions/checkout@v4
- run: |
ls ${{ github.workspace }}

View file

@ -0,0 +1,6 @@
on: [push]
jobs:
test:
runs-on: docker
steps:
- run: sleep infinity

20
testdata/example-push-cancel/run.sh vendored Executable file
View file

@ -0,0 +1,20 @@
url=http://root:admin1234@$(cat forgejo-ip):3000
token=$(cat forgejo-token)
repo=root/example-$example
#
# push the repository
#
forgejo-test-helper.sh push_workflow testdata/example-$example $url root example-$example setup-forgejo $token
sha=$(forgejo-test-helper.sh branch_tip $url $repo main)
#
# wait for the workflow (sleep infinity) to start running
#
forgejo-test-helper.sh wait_running $url $repo $sha
#
# push to the same branch
#
forgejo-test-helper.sh push_workflow testdata/example-$example $url root example-$example setup-forgejo $token
#
# wait for the workflow to be canceld as a result of the previous push
#
forgejo-test-helper.sh wait_failure $url $repo $sha 'Has been cancelled'

View file

@ -0,0 +1,4 @@
#
# this will effectively discard any linger workflow so they do not interfere with other tests
#
forgejo-runner.sh reload

View file

@ -1,19 +0,0 @@
on: [push]
jobs:
test:
runs-on: docker
container:
image: code.forgejo.org/oci/debian:bookworm
services:
pgsql:
image: code.forgejo.org/oci/postgres:15
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
steps:
- run: |
apt-get update -qq
apt-get install -y -qq postgresql-client
PGPASSWORD=postgres psql -h pgsql -U postgres -c '\dt' test

View file

@ -2,9 +2,29 @@ on: [push]
jobs: jobs:
# #
# No volume involved
#
simple:
runs-on: docker
container:
image: code.forgejo.org/oci/debian:bookworm
services:
pgsql:
image: code.forgejo.org/oci/postgres:15
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
steps:
- run: |
apt-get update -qq
apt-get install -y -qq postgresql-client
PGPASSWORD=postgres psql -h pgsql -U postgres -c '\dt' test
#
# A --volume option will expose the volume from the docker host to the job # A --volume option will expose the volume from the docker host to the job
# #
volume-on-step: volume-on-step:
needs: [simple]
runs-on: docker runs-on: docker
container: container:
image: code.forgejo.org/oci/debian:bookworm image: code.forgejo.org/oci/debian:bookworm
@ -19,6 +39,7 @@ jobs:
# A --volume option will expose the volume from the docker host to the service # A --volume option will expose the volume from the docker host to the service
# #
volume-on-service: volume-on-service:
needs: [volume-on-step]
runs-on: docker runs-on: docker
container: container:
image: code.forgejo.org/oci/debian:bookworm image: code.forgejo.org/oci/debian:bookworm