This JavaScript GitHub Action can be used to impersonate a GitHub App when secrets.GITHUB_TOKEN
's limitations are too restrictive and a personal access token is not suitable.
For instance, from GitHub Actions' docs:
When you use the repository's
GITHUB_TOKEN
to perform tasks, events triggered by theGITHUB_TOKEN
, with the exception ofworkflow_dispatch
andrepository_dispatch
, will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs. For example, if a workflow run pushes code using the repository'sGITHUB_TOKEN
, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.
A workaround is to use a personal access token from a personal user/bot account. However, for organizations, GitHub Apps are a more appropriate automation solution.
Here is a generic example retrieving a token from a GitHub App using this action, then consuming that token in a subsequent step. You can see some of the optional inputs listed in comments, as well.
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Generate token
id: generate_token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.APP_ID }}
# Optional.
# github_api_url: https://api.example.com
# Optional.
# installation_id: 1337
# Optional.
# Using a YAML multiline string to avoid escaping the JSON quotes.
# permissions: >-
# {"members": "read"}
private_key: ${{ secrets.PRIVATE_KEY }}
# Optional.
# repository: owner/repo
- name: Use token
env:
TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
echo "The generated token is masked: ${TOKEN}"
Another use case for this action can (or could) be found in GitHub's own docs.
This action is a great way to securely clone private submodules, a common need that remains unsupported by GitHub Actions as described in actions/checkout issue 287. Using GitHub App integration to clone submodules does not consume a paid user seat with a service account, the secrets cannot be used to login to the GitHub web UI, and the token used for the clone expires after one hour.
Steps:
- Create a GitHub App.
- Profile > Your organizations > Organization Settings > GitHub Apps > New GitHub App
- Fill in the information for the app.
- GitHub App name:
${REPO_NAME}-ci-submodule-checkout
- Description:
This GitHub application is used by the ${REPO_NAME} CICD pipeline(s) to clone private submodules by using a fork of the tibdex/github-app-token GitHub Action to obtain an ephemeral token from this app and assume its identity. This token expires after one hour.
- Homepage URL:
${REPO_URL}
- Ensure the
Expire user authorization tokens
checkbox is checked. - Disable webhook notifications.
- Permissions > Repository permissions > Contents > Read-only
- This will implicitly set
Metadata
toRead-only
as well.
- This will implicitly set
- For
Where can this integration be installed?
chooseOnly on this account
.
- GitHub App name:
- Click
Create GitHub App
.
- Obtain credentials to assume the identity of the app.
- Profile > Your organizations > Developer settings > GitHub Apps >
${REPO_NAME}-ci-submodule-checkout
> Edit - Private keys > Generate a private key
- A private key downloads to your computer as a
*.pem
file. Keep this secret. - Note the app ID. Keep this secret.
- Profile > Your organizations > Developer settings > GitHub Apps >
- Install the app in the organization.
- Organization > Settings > GitHub Apps >
${REPO_NAME}-ci-submodule-checkout
> Edit - Install App
- Click
Install
for the desired organization. Install & Request
on your organization > Only select repositories- If you are an org admin, the button may be labeled differently.
- Select the appropriate repos in the drop-down.
- This must include both the submodules you wish to clone as well as the repo you are cloning them into!
Ask me how I know, lol.
- This must include both the submodules you wish to clone as well as the repo you are cloning them into!
- Click
Install & Request
.- If you are an org admin, the button may be labeled differently.
- Organization > Settings > GitHub Apps >
- Create repo secrets for app integration.
- Repo > Settings > Secrets and variables > Actions
- Add two new secrets.
${REPO_NAME}_CI_APP_ID ${REPO_NAME}_CI_APP_KEY
- Use the GitHub App to clone private submodules in your GitHub Actions workflow(s).
name: CI on: [push, workflow_dispatch] jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Authenticate id: auth uses: AntelopeIO/github-app-token-action@v1 with: app_id: ${{ secrets.${REPO_NAME}_CI_APP_ID }} private_key: ${{ secrets.${REPO_NAME}_CI_APP_KEY }} - name: Checkout Repo uses: actions/checkout@v3 with: fetch-depth: 0 submodules: 'recursive' token: ${{ steps.auth.outputs.token }} - name: Do a Thing run: tree -L 2
Don't forget to replace ${REPO_NAME}
and ${REPO_URL}
with the appropriate values if you copy/pasta these examples.
The author recommends using a different GitHub App integration for each repo cloning submodules. This allows you to follow the principle of least priviledge.
Credit to @petr-tichy for the idea, and @matthijskooijman for sharing detailed steps to accomplish this. Thank you both!
When a commit is pushed to the base branch (main
), the dylanvann/publish-github-action GitHub Action is invoked. If the version
field in the package.json
is new, then the action:
- Downloads dependencies.
- Builds the project.
- Packs the action as a minimal distributable.
- Puts these files on a branch named "
releases/
" with the version string appended to the end. - Points tags corresponding to the major, minor, and patch versions at the
HEAD
of the newrelease*
branch.
For example, if the version
field in package.json
is 1.1.1
, the following refs will be created.
- A branch named
releases/v1.1.1
with the action built and other files removed. - A tag named
v1.1.1
is created pointing at theHEAD
ofreleases/v1.1.1
. - A tag named
v1.1
is moved or created, pointing at theHEAD
ofreleases/v1.1.1
. - A tag named
v1
is moved or created, pointing at theHEAD
ofreleases/v1.1.1
.
It is important to note some repo protections will prevent this action from running.
- Tag protections.
- Branch protections matching the release pattern.
- Code signing requirements.
If these are enforced, they must be disabled for the action to run.