diff --git a/.github/workflows/Format.yml b/.github/workflows/Format.yml index be7fd53f..9decb87b 100644 --- a/.github/workflows/Format.yml +++ b/.github/workflows/Format.yml @@ -18,7 +18,12 @@ jobs: - name: Check out repository uses: actions/checkout@v7 with: - ref: ${{github.event.pull_request.head.ref}} + # Checking out fork code in a pull_request_target workflow requires an explicit + # opt-in since checkout v7. Safe here: the PR code is only parsed by Runic, + # never executed, and we drop the credentials and pin the event's head SHA. + allow-unsafe-pr-checkout: true + persist-credentials: false + ref: ${{github.event.pull_request.head.sha}} repository: ${{github.event.pull_request.head.repo.full_name}} fetch-depth: 0 diff --git a/.github/workflows/alcf.yml b/.github/workflows/alcf.yml index 8896a932..51f2af07 100644 --- a/.github/workflows/alcf.yml +++ b/.github/workflows/alcf.yml @@ -12,6 +12,12 @@ name: ALCF CI # which pushes the PR head to GitLab as branch gh-pr- and triggers a pipeline. # Re-apply the label to re-run after new pushes. This workflow only moves refs; it # never checks out or executes PR code. +# +# The push uses ci.skip and the pipeline is created through a pipeline trigger token +# (ALCF_GITLAB_TRIGGER_TOKEN secret) instead: ALCF_GITLAB_TOKEN is a project access +# token, i.e. a bot user, and ALCF's Jacamar runners refuse bot-attributed pipelines +# ("bot account token used for job, unsupported by runner"). Trigger-token pipelines +# run as the user who created the token, which Jacamar accepts. on: push: @@ -45,6 +51,7 @@ jobs: GITLAB_PROJECT: mschanen/oneAPI-jl API: https://gitlab-ci.alcf.anl.gov/api/v4/projects/238 GITLAB_TOKEN: ${{ secrets.ALCF_GITLAB_TOKEN }} + GITLAB_TRIGGER_TOKEN: ${{ secrets.ALCF_GITLAB_TRIGGER_TOKEN }} HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} steps: - name: Push fork PR head to GitLab (label-gated) @@ -52,14 +59,28 @@ jobs: env: PR: ${{ github.event.pull_request.number }} run: | + if [ -z "$GITLAB_TRIGGER_TOKEN" ]; then + echo "::error::ALCF_GITLAB_TRIGGER_TOKEN secret not set (create a pipeline trigger token in the GitLab project settings)" + exit 1 + fi git init -q head && cd head git fetch -q "https://github.com/$GITHUB_REPOSITORY" "pull/$PR/head" if [ "$(git rev-parse FETCH_HEAD)" != "$HEAD_SHA" ]; then echo "::error::PR head moved since labeling; re-apply the label" exit 1 fi - git push -q -f "https://oauth2:${GITLAB_TOKEN}@${GITLAB_HOST}/${GITLAB_PROJECT}.git" \ + # ci.skip: a push pipeline would be attributed to the project access token's + # bot user, which the Jacamar runners refuse (see header comment). Move the + # ref only, then create the pipeline via the trigger token below. + git push -q -f -o ci.skip \ + "https://oauth2:${GITLAB_TOKEN}@${GITLAB_HOST}/${GITLAB_PROJECT}.git" \ "FETCH_HEAD:refs/heads/gh-pr-$PR" + RESP=$(curl -sS -X POST "$API/trigger/pipeline" \ + -F "token=${GITLAB_TRIGGER_TOKEN}" -F "ref=gh-pr-$PR") + if ! echo "$RESP" | jq -e '.id' >/dev/null 2>&1; then + echo "::error::failed to trigger GitLab pipeline: $RESP" + exit 1 + fi - name: Force mirror sync if: github.event_name != 'pull_request_target' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e305ab0..095f176e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,10 @@ include: workflow: rules: - - if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "api" + # "trigger" covers fork-PR pipelines, created via a pipeline trigger token by + # .github/workflows/alcf.yml so they run as a real user instead of the mirror + # project's bot (which the Jacamar runners refuse). + - if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "api" || $CI_PIPELINE_SOURCE == "trigger" default: interruptible: true # force-pushes cancel stale runs instead of queueing behind them