diff --git a/.forgejo/workflows/integration.yml b/.forgejo/workflows/integration.yml index dfdc3bd..a7eb22c 100644 --- a/.forgejo/workflows/integration.yml +++ b/.forgejo/workflows/integration.yml @@ -6,9 +6,9 @@ jobs: strategy: matrix: info: - - version: "1.21.0-0-rc0" + - version: "1.21.0-1-rc0" image: codeberg.org/forgejo-experimental/forgejo - tests: "echo cron service container expression local-action docker-action if if-fail" + tests: "echo cron pull-request service container expression local-action docker-action if if-fail" - version: "1.20" image: codeberg.org/forgejo/forgejo tests: "echo service container expression local-action docker-action if if-fail" @@ -31,15 +31,16 @@ jobs: export FORGEJO_RUNNER_LOGS=forgejo-runner.log for example in ${{ matrix.info.tests }} ; do + export example export EXAMPLE_DIR=$(pwd)/testdata/example-$example if test -f $EXAMPLE_DIR/setup.sh ; then - source $EXAMPLE_DIR/setup.sh + $EXAMPLE_DIR/setup.sh fi echo "============================ BEGIN example-$example ===================" if test -f $EXAMPLE_DIR/run.sh ; then - source $EXAMPLE_DIR/run.sh + $EXAMPLE_DIR/run.sh else if ! forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token) >& /tmp/run.out ; then cat /tmp/run.out @@ -49,7 +50,7 @@ jobs: echo "============================ END example-$example ===================" if test -f $EXAMPLE_DIR/teardown.sh ; then - source $EXAMPLE_DIR/teardown.sh + $EXAMPLE_DIR/teardown.sh fi done echo "============================ demo ===================" diff --git a/README.md b/README.md index b3d0111..81cd769 100644 --- a/README.md +++ b/README.md @@ -88,3 +88,20 @@ jobs: ## Hacking * Update the README from the action file with https://github.com/npalm/action-docs `action-docs --update-readme` + +To manually run and debug workflows from `testdata/example-*`, from +the root of the source directory, with docker and forgejo-curl.sh +installed, mimic what `.forgejo/workflows/integration.yml` does. There +may be some manual tweaking (such as creating temporary directories) +because the tests run as root, but they do not need to run as root. + +* `forgejo-curl.sh logout` +* `forgejo.sh setup root admin1234 codeberg.org/forgejo/forgejo 1.21` +* `firefox http://$(cat forgejo-ip):3000` +* `forgejo-runner.sh setup` +* `export example=pull-request` +* `export EXAMPLE_DIR=$(pwd)/testdata/example-$example` +* `$EXAMPLE_DIR/setup.sh` # if it exists +* `$EXAMPLE_DIR/run.sh` +* `forgejo-runner.sh teardown` +* `forgejo.sh teardown` diff --git a/forgejo-test-helper.sh b/forgejo-test-helper.sh index 39ad372..adc5d18 100755 --- a/forgejo-test-helper.sh +++ b/forgejo-test-helper.sh @@ -3,6 +3,8 @@ set -ex +export DEBIAN_FRONTEND=noninteractive + : ${LOOPS:=40} : ${LOOP_DELAY:=10} DIR=$(mktemp -d) diff --git a/testdata/example-pull-request/.forgejo/workflows/test.yml b/testdata/example-pull-request/.forgejo/workflows/test.yml new file mode 100644 index 0000000..1e6ad0b --- /dev/null +++ b/testdata/example-pull-request/.forgejo/workflows/test.yml @@ -0,0 +1,123 @@ +on: + pull_request: + pull_request_target: + types: + - opened + - synchronize + +jobs: + test: + runs-on: docker + container: + image: debian:bookworm + options: "--volume /srv/example-pull-request:/srv/example-pull-request" + + steps: + - name: setup + shell: bash + run: | + set -x + test $GITHUB_TOKEN = ${{ env.GITHUB_TOKEN }} + test $GITHUB_TOKEN = ${{ github.token }} + export DEBIAN_FRONTEND=noninteractive ; apt-get -qq update ; apt-get install -y -qq curl git >& /dev/null + curl -sS -o /usr/local/bin/forgejo-curl.sh https://code.forgejo.org/forgejo/forgejo-curl/raw/branch/main/forgejo-curl.sh && chmod +x /usr/local/bin/forgejo-curl.sh + forgejo-curl.sh --token "$GITHUB_TOKEN" login $GITHUB_SERVER_URL + forgejo-curl.sh api_json $GITHUB_SERVER_URL/api/v1/user + + - name: secrets + shell: bash + run: | + set -x + if test ${{ github.event.pull_request.base.repo.full_name }} = ${{ github.event.pull_request.head.repo.full_name }} ; then + forked=false + else + forked=true + fi + case $GITHUB_EVENT_NAME in + pull_request_target) + # + # all PRs: secrets + # + test "${{ secrets.SECRET }}" + ;; + pull_request) + if $forked ; then + # + # PRs from forked repositories: no secrets + # + test -z "${{ secrets.SECRET }}" + else + # + # PRs from the same repository: secrets + # + test "${{ secrets.SECRET }}" + fi + ;; + *) + echo unexpected event $GITHUB_EVENT_NAME + false + ;; + esac + + - name: PR TOKEN scopes + shell: bash + run: | + set -x + if test ${{ github.event.pull_request.base.repo.full_name }} = ${{ github.event.pull_request.head.repo.full_name }} ; then + forked=false + else + forked=true + fi + function assert_fail_if_forked() { + if "$@" ; then + ! $forked + else + $forked + fi + } + # + # create an issue + # + base_repo=${{ github.event.pull_request.base.repo.full_name }} + forgejo-curl.sh api_json --data-raw '{"title":"ISSUE"}' $GITHUB_SERVER_URL/api/v1/repos/$base_repo/issues + url=$(echo $GITHUB_SERVER_URL | sed -e "s|://|://$GITHUB_TOKEN@|") + git clone $url/$base_repo base + branch=B$RANDOM + ( + cd base + git checkout -b $branch + git config user.email root@example.com + git config user.name username + echo CHANGE >> README + git add . + git commit -m 'change' + case $GITHUB_EVENT_NAME in + pull_request_target|pull_request) + # + # repository write scope via http git passthrough + # + assert_fail_if_forked git push --force -u origin $branch + # + # repository write scope via the API + # + assert_fail_if_forked forgejo-curl.sh api_json --data-raw '{"title":"PR","base":"main","head":"'$branch'"}' $GITHUB_SERVER_URL/api/v1/repos/$base_repo/pulls + assert_fail_if_forked forgejo-curl.sh api_json --data-raw '{"color":"#ffffff","name":"labelname"}' $GITHUB_SERVER_URL/api/v1/repos/$base_repo/labels + # + # See https://codeberg.org/forgejo/forgejo/issues/1525 + # + ! forgejo-curl.sh api_json --data-raw '{"new_branch_name":"B'$RANDOM'"}' $GITHUB_SERVER_URL/api/v1/repos/$base_repo/branches + ;; + *) + echo unexpected event $GITHUB_EVENT_NAME + false + ;; + esac + ) + + - name: save event + run: | + d=/srv/example-pull-request/${{ github.event.pull_request.head.repo.owner.username }}/$GITHUB_EVENT_NAME/${{ github.event.action }} + mkdir -p $d + cat > $d/event <> README + git add . + git commit -m 'fork change' + git push + ) + + forgejo.sh retry forgejo-curl.sh api_json --data-raw '{"title":"PR from fork","base":"main","head":"fork-org:main"}' $api/repos/root/example-pull-request/pulls + + ( + cd $d + git clone $url/root/example-pull-request + cd example-pull-request + git checkout -b other + git config user.email root@example.com + git config user.name username + echo other $PROOF >> README + git add . + git commit -m 'other change' + git push --force -u origin other + ) + + forgejo.sh retry forgejo-curl.sh api_json --data-raw '{"title":"PR same repo","base":"main","head":"other"}' $api/repos/root/example-pull-request/pulls + + export RETRY_DELAYS="60 60 60 60 60 60 60" + for assert in $EXAMPLE_DIR/assert-*.sh ; do + if ! forgejo.sh retry $assert ; then + find $d + cat $FORGEJO_RUNNER_LOGS + false + fi + done +} + +function main() { + setup +} + +main diff --git a/testdata/example-pull-request/runner-config.yaml b/testdata/example-pull-request/runner-config.yaml new file mode 100644 index 0000000..7f7d9cc --- /dev/null +++ b/testdata/example-pull-request/runner-config.yaml @@ -0,0 +1,30 @@ + +log: + level: info + +runner: + file: .runner + capacity: 1 + env_file: .env + timeout: 3h + insecure: false + fetch_timeout: 5s + fetch_interval: 2s + labels: [] + +cache: + enabled: false + dir: "" + host: "" + port: 0 + +container: + network: "bridge" + privileged: false + options: + workdir_parent: + valid_volumes: ["/srv/example-pull-request"] + docker_host: "" + +host: + workdir_parent: diff --git a/testdata/example-pull-request/setup.sh b/testdata/example-pull-request/setup.sh new file mode 100755 index 0000000..f2c4556 --- /dev/null +++ b/testdata/example-pull-request/setup.sh @@ -0,0 +1,2 @@ +mkdir -p /srv/example-pull-request +FORGEJO_RUNNER_CONFIG=$EXAMPLE_DIR/runner-config.yaml forgejo-runner.sh reload diff --git a/testdata/example-pull-request/teardown.sh b/testdata/example-pull-request/teardown.sh new file mode 100755 index 0000000..b410c51 --- /dev/null +++ b/testdata/example-pull-request/teardown.sh @@ -0,0 +1 @@ +forgejo-runner.sh reload