diff --git a/.github/actions/release-candidate/action.yml b/.github/actions/release-candidate/action.yml index 6b2d59f..3af67ba 100644 --- a/.github/actions/release-candidate/action.yml +++ b/.github/actions/release-candidate/action.yml @@ -85,6 +85,27 @@ runs: echo "version=$version" >> "$GITHUB_OUTPUT" echo "release version: $version" + - name: Configure git auth + shell: bash + env: + TOKEN: ${{ inputs.token }} + NAME: ${{ inputs.git_user_name }} + EMAIL: ${{ inputs.git_user_email }} + run: | + set -euo pipefail + git config user.name "$NAME" + git config user.email "$EMAIL" + # Same mechanism actions/checkout uses, scoped to this clone and + # removed in the last step. Drop any header a persisted checkout left + # behind first: git sends every configured extraheader, and two + # Authorization headers get a 400. + git config --unset-all "http.https://github.com/.extraheader" || true + auth="$(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + # The token itself is masked by create-github-app-token; its base64 + # form is not, so mask it too before it can reach a log. + echo "::add-mask::$auth" + git config "http.https://github.com/.extraheader" "AUTHORIZATION: basic $auth" + # ---------------------------------------------------------------- propose - name: Guard (propose) if: inputs.stage == 'propose' @@ -130,6 +151,13 @@ runs: echo "$FILE: $old -> $VERSION" git diff --stat + # create-pull-request authenticates its own push with the token input; + # hand it a clone without our header so the two never overlap. + - name: Remove git auth before opening the PR + if: inputs.stage == 'propose' + shell: bash + run: git config --unset-all "http.https://github.com/.extraheader" || true + - name: Open candidate PR if: inputs.stage == 'propose' id: pr @@ -188,3 +216,8 @@ runs: gh api "repos/$GITHUB_REPOSITORY/git/refs" -f ref="refs/heads/$branch" -f sha="$MERGE_SHA" >/dev/null echo "release_branch=$branch" >> "$GITHUB_OUTPUT" echo "created $branch at $MERGE_SHA" + + - name: Remove git auth + if: always() + shell: bash + run: git config --unset-all "http.https://github.com/.extraheader" || true diff --git a/.github/actions/release-publish/action.yml b/.github/actions/release-publish/action.yml index 67946ab..5e92b3f 100644 --- a/.github/actions/release-publish/action.yml +++ b/.github/actions/release-publish/action.yml @@ -60,6 +60,27 @@ outputs: runs: using: composite steps: + - name: Configure git auth + shell: bash + env: + TOKEN: ${{ inputs.token }} + NAME: ${{ inputs.git_user_name }} + EMAIL: ${{ inputs.git_user_email }} + run: | + set -euo pipefail + git config user.name "$NAME" + git config user.email "$EMAIL" + # Same mechanism actions/checkout uses, scoped to this clone and + # removed in the last step. Drop any header a persisted checkout left + # behind first: git sends every configured extraheader, and two + # Authorization headers get a 400. + git config --unset-all "http.https://github.com/.extraheader" || true + auth="$(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + # The token itself is masked by create-github-app-token; its base64 + # form is not, so mask it too before it can reach a log. + echo "::add-mask::$auth" + git config "http.https://github.com/.extraheader" "AUTHORIZATION: basic $auth" + - name: Guard id: guard shell: bash @@ -122,19 +143,6 @@ runs: } >> "$GITHUB_OUTPUT" echo "publishing v$version at $MERGE_SHA"; echo "--- notes ---"; cat "$notes" - - name: Configure git auth - shell: bash - env: - TOKEN: ${{ inputs.token }} - NAME: ${{ inputs.git_user_name }} - EMAIL: ${{ inputs.git_user_email }} - run: | - set -euo pipefail - git config user.name "$NAME" - git config user.email "$EMAIL" - git config "http.https://github.com/.extraheader" \ - "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" - - name: Create and push tag id: tag shell: bash @@ -183,7 +191,7 @@ runs: exit 0 fi git commit --quiet -m "chore(release): changelog for v$VERSION" - git push --quiet --force-with-lease origin "$head" + git push --quiet --force origin "$head" url="$(gh pr create --base "$default" --head "$head" \ --title "chore(release): changelog for v$VERSION" \ --body "Back-merge of \`$CHANGELOG\` from \`$TAG\` into \`$default\`, opened by release-publish.")" diff --git a/.github/actions/release-settle/action.yml b/.github/actions/release-settle/action.yml index bef04e9..7711aba 100644 --- a/.github/actions/release-settle/action.yml +++ b/.github/actions/release-settle/action.yml @@ -59,6 +59,27 @@ outputs: runs: using: composite steps: + - name: Configure git auth + shell: bash + env: + TOKEN: ${{ inputs.token }} + NAME: ${{ inputs.git_user_name }} + EMAIL: ${{ inputs.git_user_email }} + run: | + set -euo pipefail + git config user.name "$NAME" + git config user.email "$EMAIL" + # Same mechanism actions/checkout uses, scoped to this clone and + # removed in the last step. Drop any header a persisted checkout left + # behind first: git sends every configured extraheader, and two + # Authorization headers get a 400. + git config --unset-all "http.https://github.com/.extraheader" || true + auth="$(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + # The token itself is masked by create-github-app-token; its base64 + # form is not, so mask it too before it can reach a log. + echo "::add-mask::$auth" + git config "http.https://github.com/.extraheader" "AUTHORIZATION: basic $auth" + - name: Guard id: guard shell: bash @@ -119,20 +140,6 @@ runs: echo "notes_file=$notes" >> "$GITHUB_OUTPUT" echo "--- release notes ---"; cat "$notes" - - name: Configure git auth - shell: bash - env: - TOKEN: ${{ inputs.token }} - NAME: ${{ inputs.git_user_name }} - EMAIL: ${{ inputs.git_user_email }} - run: | - set -euo pipefail - git config user.name "$NAME" - git config user.email "$EMAIL" - # Same mechanism actions/checkout uses; scoped to this clone, removed below. - git config "http.https://github.com/.extraheader" \ - "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" - - name: Write changelog and open settle PR id: pr shell: bash @@ -151,7 +158,7 @@ runs: what="$(python3 "$TOOLS" changelog-insert "$CHANGELOG" "$VERSION" "$NOTES")" git add "$CHANGELOG" git commit --quiet -m "chore(release): settle v$VERSION" -m "Changelog entry $what for v$VERSION at $COMMIT." - git push --quiet --force-with-lease origin "$head" + git push --quiet --force origin "$head" body="$RUNNER_TEMP/settle-pr-body.md" { echo "Settle **v$VERSION** at \`$COMMIT\` (tip of \`$BRANCH\`)." diff --git a/.github/actions/release-tools/__pycache__/release_tools.cpython-314.pyc b/.github/actions/release-tools/__pycache__/release_tools.cpython-314.pyc index e6416d2..9001b8e 100644 Binary files a/.github/actions/release-tools/__pycache__/release_tools.cpython-314.pyc and b/.github/actions/release-tools/__pycache__/release_tools.cpython-314.pyc differ diff --git a/.github/actions/release-tools/__pycache__/test_release_tools.cpython-314.pyc b/.github/actions/release-tools/__pycache__/test_release_tools.cpython-314.pyc index b4715a3..60fe62c 100644 Binary files a/.github/actions/release-tools/__pycache__/test_release_tools.cpython-314.pyc and b/.github/actions/release-tools/__pycache__/test_release_tools.cpython-314.pyc differ