Skip to content

Instantly share code, notes, and snippets.

@swinton
Last active March 25, 2024 03:56
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save swinton/03e84635b45c78353b1f71e41007fc7c to your computer and use it in GitHub Desktop.
Save swinton/03e84635b45c78353b1f71e41007fc7c to your computer and use it in GitHub Desktop.
Automatically sign your commits from GitHub Actions, using the REST API

Verified commits made easy with GitHub Actions

image

So you want to commit changes generated by a GitHub Actions workflow back to your repo, and have that commit signed automatically?

Here's one way this is possible, using the REST API, the auto-generated GITHUB_TOKEN, and the GitHub CLI, gh, which is pre-installed on GitHub's hosted Actions runners.

You don't have to configure the git client, just add a step like the one below... Be sure to edit FILE_TO_COMMIT and DESTINATION_BRANCH to suit your needs.

    # Use the REST API to commit changes, so we get automatic commit signing
    - name: Commit changes
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        FILE_TO_COMMIT: data.csv
        DESTINATION_BRANCH: data
      run: |
        export TODAY=$( date -u '+%Y-%m-%d' )
        export MESSAGE="chore: regenerate $FILE_TO_COMMIT for $TODAY"
        export SHA=$( git rev-parse $DESTINATION_BRANCH:$FILE_TO_COMMIT )
        export CONTENT=$( base64 -i $FILE_TO_COMMIT )
        gh api --method PUT /repos/:owner/:repo/contents/$FILE_TO_COMMIT \
          --field message="$MESSAGE" \
          --field content="$CONTENT" \
          --field encoding="base64" \
          --field branch="$DESTINATION_BRANCH" \
          --field sha="$SHA"

Caveats

Because of the underlying REST API, only 1 file can be committed at a time.

Notes

This is made possible because GitHub automatically signs commits from bots over the REST API. Since the GITHUB_TOKEN is a bot token, this also applies to commits from GitHub Actions.

See this blog post from 2019 for more details: https://github.blog/2019-08-15-commit-signing-support-for-bots-and-other-github-apps/

@andrewfraley
Copy link

You da real MVP. Thanks.

@jkribeiro
Copy link

I'm not having the same luck, I'm having:

{"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/reference/repos#create-or-update-file-contents"}```

@swinton
Copy link
Author

swinton commented Jun 3, 2022

I'm not having the same luck, I'm having:

{"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/reference/repos#create-or-update-file-contents"}```

@jkribeiro is it possible you are using the GITHUB_TOKEN to commit to a different repo from the one running the workflow? If so, you’ll need a separate token for this. GITHUB_TOKEN is repo-scoped.

@jannisborn
Copy link

Good solution, just note that this will not work per se for protected branches since GITHUB_TOKEN does not have admin rights

@dwoffinden
Copy link

dwoffinden commented Jul 1, 2022

Thanks for this. I found that for large files I was getting an error (/usr/bin/gh: Argument list too long), and fixed it by having gh read from a file (or bash's process substitution) rather than passing the contents on the argument list:

-          export CONTENT=$( base64 -i $FILE_TO_COMMIT )                               
           gh api --method PUT /repos/:owner/:repo/contents/$FILE_TO_COMMIT \
             --field message="$MESSAGE" \
-            --field content="$CONTENT" \                                              
-            --field encoding="base64" \                                               
+            --field content=@<( base64 -i $FILE_TO_COMMIT ) \  

(See the --field docs @ https://cli.github.com/manual/gh_api)

@radupopa2010
Copy link

Thank you for sharing this info

@maboloshi
Copy link

In fact, using the GitHub GraphQL API, you can add and delete multiple files at the same time with a github web-flow signature.

My own script: ci_commit_with_signature.sh

@qoomon
Copy link

qoomon commented Mar 21, 2024

I create a GitHub Action to hide this complexity => https://github.com/qoomon/actions--create-commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment