GitHub Automation with Mint
Before implementing a GitHub Automation workflow, see the getting started guide.
In this guide, you will set up a private GitHub App to automate the process of performing a routine code update and creating or updating a pull request.
GitHub Automation can be combined with cron schedules to automate tasks like dependency updates.
Set up GitHub App
During initial setup, you already installed the Mint GitHub App.
To update code and open a pull request, you will create a new, private GitHub App owned by your GitHub organization or user, then give it additional permissions. In Mint, all private GitHub Apps are added to a vault to control access to its elevated permissions.
To begin, go to Vaults and select or create the vault to
contain the private GitHub App. Select GitHub Apps
and Add GitHub App
.
Enter the GitHub organization slug, or select that you'd like to create the app in your personal GitHub account. A private GitHub app can only be installed by its owner and won't be available to other organizations (GitHub or Mint).
You'll be sent to GitHub to complete creation of the app. Enter an app name,
which must be globally unique, and Continue
.
Once you've returned to Mint, select the three-dot menu for your new GitHub App
and Manage App
then Permissions and Events
to add necessary permissions.
For this guide, expand Repository permissions
and change:
Contents: Read and write
to allow pushing updates to branchesPull requests: Read and write
to allow creating new pull requests
Return to the Mint vault with your GitHub App, select
the three-dot menu and Install
. Once you accept the installation on
GitHub, you'll return to Mint and see the app is now installed.
Remember to select the repositories that this app should have access to.
Any time your GitHub App's permissions are updated, the new permissions
must be approved for the installation. You can use Manage Installation
from the three-dot menu here to navigate to this GitHub page quickly.
See GitHub's documentation on changing app permissions for more information.
Capture the vault name and GitHub App Slug
for use in the next step.
Shared Mint run configuration
In this example, assume the following:
- Vault name is
YOUR_VAULT
- GitHub App Slug is
YOUR-GITHUB-APP-SLUG
- GitHub repository is at
https://github.com/YOUR-ORG/YOUR-REPO.git
Open a pull request
With the assumptions made in Shared Mint run configuration, let's make a very simple workflow that opens a new GitHub pull request.
Create a new Mint configuration at .mint/update-timestamp.yml
with the contents:
tasks:
- key: github-cli
call: github/install-cli 1.0.1
- key: code
call: mint/git-clone 1.5.0
with:
repository: https://github.com/YOUR-ORG/YOUR-REPO.git
ref: ${{ init.commit-sha }}
preserve-git-dir: true
github-access-token: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
- key: update-code
use: code
cache: false
run: |
git checkout -b "update-timestamp-$(date +%s)"
date -Iseconds > timestamp.txt
git add timestamp.txt
git commit -m "Update timestamp."
git push -u origin "$(git rev-parse --abbrev-ref HEAD)"
env:
GITHUB_TOKEN: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
- key: create-pr
use: [github-cli, update-code]
run: gh pr create --fill
env:
GITHUB_TOKEN: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
On every run, let's create a new branch, update timestamp.txt
, and open a pull request.
Test this configuration from your local machine with:
mint run --file .mint/update-timestamp.yml --init commit-sha=main
Update or open a pull request
With the assumptions made in Shared Mint run configuration, let's make a workflow that can update an existing pull request, or create a pull request if one doesn't exist. Mint will use a filter and only update a pull request created by your private GitHub App.
In this example, the Mint configuration will:
- Update a file with the latest 4-week U.S. Treasury Bill auction result
- If there are new results and there is no open pull request created by this app, open a new pull request
- If there are new results and there is an open pull request created by this app, push a new commit to the pull request branch
- Otherwise, do nothing
Create a new Mint configuration at .mint/update-auction.yml
with the contents:
tasks:
- key: jq
run: |
sudo apt-get update
sudo apt-get install jq
sudo apt-get clean
- key: github-cli
call: github/install-cli 1.0.1
- key: code
call: mint/git-clone 1.5.0
with:
repository: https://github.com/YOUR-ORG/YOUR-REPO.git
ref: ${{ init.commit-sha }}
preserve-git-dir: true
github-access-token: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
- key: update-code
use: [jq, github-cli, code]
cache: false
run: |
# Capture the last open pull request made by this app in this repository.
# The gh cli will detect the current repository and automatically filter to it.
# Checkout its branch or create a new one.
pr_number="$(gh pr list --author '@me' --json number --jq 'max_by(.number) | .number')"
printf "$pr_number" > "$MINT_VALUES/existing-pr"
if [ -n "$pr_number" ]; then
gh pr checkout "$pr_number"
else
git checkout -b "update-auction-results-$(date +%s)"
fi
# Download the latest auction results.
treasury_url="https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v1/accounting/od/auctions_query?fields=auction_date,high_investment_rate,cusip&filter=security_term:eq:4-Week,auction_date:gte:$(date -d '-28 days' -I),auction_date:lte:$(date -I)"
curl "$treasury_url" | jq '.data | max_by(.auction_date)' > 4-week.json
# Commit and push changes.
if [ -n "$(git status --porcelain)" ]; then
printf "true" > "$MINT_VALUES/has-changes"
git add 4-week.json
git commit -m "Update Treasury auction results."
git push -u origin "$(git rev-parse --abbrev-ref HEAD)"
else
printf "false" > "$MINT_VALUES/has-changes"
fi
outputs:
values: [existing-pr, has-changes]
env:
GITHUB_TOKEN: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
- key: create-pr
use: update-code
if: ${{ tasks.update-code.values.has-changes == "true" && tasks.update-code.values.existing-pr == "" }}
run: gh pr create --fill
env:
GITHUB_TOKEN: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
If an open pull request created by your private GitHub App was found, pushing to
its branch will update the pull request. Otherwise, Mint will conditionally run
create-pr
to open a new pull request using an if
condition.
Test this configuration from your local machine with:
mint run --file .mint/update-auction.yml --init commit-sha=main
Comment on a pull request
In this example, Mint will create a workflow that runs when pull requests are opened or updated, calculate the approximate working directory size on disk, and output its results in pull request comment.
An on
event trigger is
included, but that only applies when this Mint configuration has been pushed into
your default GitHub branch. Let's just manually run this.
Create a new Mint configuration at .mint/pull-request-size.yml
with the contents:
on:
github:
pull_request:
init:
commit-sha: ${{ event.git.sha }}
pr-number: ${{ event.github.pull_request.number }}
tasks:
- key: github-cli
call: github/install-cli 1.0.1
- key: code
call: mint/git-clone 1.5.0
with:
repository: https://github.com/YOUR-ORG/YOUR-REPO.git
ref: ${{ init.commit-sha }}
preserve-git-dir: true
github-access-token: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
- key: pr-comment
use: [github-cli, code]
run: |
wd_size="$(du -sh --apparent-size --exclude=.git | awk '{ print $1 }')"
message="The working directory size is now: $wd_size"
# The gh cli doesn't support edit-or-create for comments.
gh pr comment "$PR_NUMBER" --edit-last --body "$message" \
|| gh pr comment "$PR_NUMBER" --body "$message" \
env:
GITHUB_TOKEN: ${{ vaults.YOUR_VAULT.github-apps.YOUR-GITHUB-APP-SLUG.token }}
PR_NUMBER: ${{ init.pr-number }}
Let's exercise it locally by manually creating a pull request in this repository and running the workflow with init parameters.
Let's assume the pull request branch name is MY-BRANCH
and its number is 98765
:
mint run --file .mint/pull-request-size.yml --init commit-sha=MY-BRANCH --init pr-number=98765