While trying to automatically generate and commit updates to docs/index.html using a .NET console app running in GitHub Actions, the workflow failed at the git push step with:
remote: Permission to Department-of-Vibes-and-Haiku-Warfare/dev-ops-and-chill.git denied to github-actions[bot].
fatal: unable to access 'https://github.com/...': The requested URL returned error: 403
contents: write permission instead of a classic PAT.git push from GitHub Actions due to limitations in how GitHub authenticates fine-grained tokens during workflow execution.github-actions[bot], resulting in denied access.repo scope.docs/index.html was staged using:
git add docs/index.html
git diff --cached.github-actions[bot] unless you override both the token and the remote URL early and correctly.This was a blood sacrifice to the CI gods, and it has been accepted.
git commit -S is not CI-friendly out of the box — it assumes an interactive TTY unless the GPG key is both trusted and unprotected.expect script, which still often fails due to /dev/tty limitations.git will fail unless GPG fully trusts the key. The normal interactive --edit-key trust dialog can’t run in CI.gpg --import-ownertrust with the full fingerprint and 6 (ultimate trust) to non-interactively trust the key:
echo "$KEY_ID:6:" | gpg --import-ownertrust
gpg.program="gpg --batch" does not work because Git interprets the string as a path. Instead:
batch mode in ~/.gnupg/gpg.confgit -c gpg.program=gpg ... in your workflowKEY_ID=$(gpg --list-secret-keys --with-colons | grep '^fpr' | head -n1 | cut -d: -f10)
echo "$KEY_ID:6:" | gpg --import-ownertrust
git -c gpg.program=gpg \
-c commit.gpgsign=true \
-c user.signingkey=$KEY_ID \
commit -S -m "Signed haiku update"
GPG signing in GitHub Actions is technically possible, but only if you’re willing to lose your entire evening and your faith in humanity.