The repository contains GitHub Action reusable workflows that can be consumed by other repositories.
GitHub provides a dependency review action to scan pull requests for vulnerabilities.
This workflow uses changed-files to output the terraform working directory which can then be used by other actions to initialise terraform. This is useful for multi directory configurations.
According to GitHubs documentation regarding Authenticating with the API, Personal Access Tokens (PATS) should be used temporarily for development work and production workflows should use GitHub App Authentication. Most GitHub Action documentation for workflows that require permissions over and above what GITHUB_TOKEN
can provide, suggest using a PAT - however I wanted to see if I could follow GitHub's advice and use an app. It can be quite easy to lose track of which PAT is stored as which action secret if you have a few of them floating around, and you don't need to worry about expiration and rotation.
This workflow uses the workflow-application-token-action to generate the installation access token using a GitHub App, which can be used in place of a Personal Access Token.
To make the workflow reusable, the output (the token), must be encrypted for use between jobs / workflows. If it isn't the runner will skip the output because it contains a secret, causing subsequent workflows to fail due to authentication errors.
Therefore some extra steps are required in the reusable workflow to encrypt the token and pass the output from the step to the workflow:
- name: Get GitHub authentication token
id: get-workflow-token
uses:
uses: peter-murray/workflow-application-token-action@v2.1.0 # Output is 'token'
- name: Encrypt the token for reuse between jobs / workflows
id: encrypt-token
env:
KEY: ${{ secrets.PGP_SECRET_SIGNING_PASSPHRASE }}
TOKEN: ${{ steps.get-workflow-token.outputs.token }}
run: |
ENCRYPTED_TOKEN=$(gpg --symmetric --batch --passphrase "$KEY" \
--output - <(echo "$TOKEN") | base64 -w0)
echo "encrypted-token=$ENCRYPTED_TOKEN" >> $GITHUB_OUTPUT
jobs:
get-temp-token:
outputs:
token: ${{ steps.encrypt-token.outputs.encrypted-token }}
workflow_call:
outputs:
temp-token:
description: "The temporary installation access token"
value: ${{ jobs.get-temp-token.outputs.token }}
The calling workflow can then access the token - but it must be decrypted before it can be used. Also remember to ::add-mask::
to prevent it being shown in the logs:
calling-workflow:
needs: get-temp-token
- name: Decrypt the installation access token
id: decrypt-token
env:
KEY: ${{ secrets.PGP_SECRET_SIGNING_PASSPHRASE }}
run: |
DECRYPTED_TOKEN=$(gpg --decrypt --quiet --batch --passphrase "$KEY" \
--output - <(echo "${{ needs.get-temp-token.outputs.temp-token }}" \
| base64 --decode))
echo "::add-mask::$DECRYPTED_TOKEN"
echo "temp-token=$DECRYPTED_TOKEN" >> $GITHUB_OUTPUT
- name: Step that required token for authentication
env:
GITHUB_TOKEN: ${{ steps.decrypt-token.outputs.temp-token }}
Thanks to this this blog post and stack overflow answer for the wise words. See get-workflow-token and release for complete workflows.
This workflow ensures that Pull Request titles follow the conventional syntax using the semantic-pull-request action. When the Pull Request is Squashed & Merged into main, the Pull Request title is used as the commit message, which is analysed by the release workflow.
Semantic Release generates tags and releases by mapping conventional commit messages to major, minor and patch version numbers. This action requires an authentication token to push the changes it generates to protected branches. It makes use of the get-workflow-token for this, instead of using a PAT.
GitHub recommends using the OSSF Scorecard action action in their Security Hardening Guide for GitHub Actions.
Terraform docs generates terraform module documentation and commits the updated README to the repository. This workflow uses get-workflow-token for authentication and ghcommit-action to push the updated README with a verified commit.
Since switching to trunk-io's GitHub App for linting, the CI badge in this document was referencing a non-existent workflow. The wait-for-checks workflow polls the checks api for the status of all the checks that run on a pull request and can be used as the sole required status check for a repository - and provide a reliable source for the CI badge.