Skip to content

Commit

Permalink
Use a GitHub App
Browse files Browse the repository at this point in the history
  • Loading branch information
joecorall committed Jan 6, 2025
1 parent 66a87e9 commit 3e38d8a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/renovate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ env:
LOG_LEVEL: debug
RENOVATE_REPOSITORIES: islandora-devops/isle-buildkit
RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS: '["bash ci/update-sha.sh \"{{{depName}}}\" \"{{{currentVersion}}}\" \"{{{newVersion}}}\" \"{{{newDigest}}}\""]'
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
jobs:
run:
runs-on: ubuntu-24.04
Expand All @@ -21,4 +20,11 @@ jobs:
with:
node-version: 20

- run: npx renovate --platform=github
- name: run renovate
run: |
# fetch GitHub App token for this repo
echo "${{ secrets.GH_APP_PRIV_KEY }}" | base64 -d > private-key.pem
export RENOVATE_TOKEN=$(./ci/fetch-app-token.sh ${{ secrets.GH_APP_ID }} ${{ secrets.GH_APP_INSTALLATION_ID }} private-key.pem)
# run renovate with our token
npx renovate --platform=github
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,8 @@ shasum -a 256 ${ALPACA_FILE}
#### Renovate

Several dependencies in this repo can be automatically updating using [renovate](https://www.mend.io/renovate/).
Several dependencies in this repo can be automatically updated using [renovate](https://www.mend.io/renovate/). Most dependencies are managed using [advanced capture](https://docs.renovatebot.com/modules/manager/regex/#advanced-capture) in the Dockerfile.


Currently these docker images have some depenencies managed by renovate:

Expand All @@ -542,7 +543,25 @@ tomcat

Since renovate does not natively support the ability to extract a sha256 from a file, we need [a custom shell script](./ci/update-sha.sh) in the [postUpgradeTasks](https://docs.renovatebot.com/configuration-options/#postupgradetasks) to calculate the sha256 of our files and update our Dockerfile accordingly.

Post upgrade tasks can only run on self-hosted Renovate instances, so this forces us to run renovate on a properly configured runner (instead of using mend.io's free GitHub app to manage our dependencies). Getting renovate setup locally looks like
Post upgrade tasks can only run on self-hosted Renovate instances, so this forces us to run renovate on a properly configured runner (instead of using mend.io's free GitHub app to manage our dependencies).

##### Running renovate (automated)

We have [a GitHub Action](./.github/workflows/renovate.yml) that runs on a schedule (or can be triggered manually) to automate generating renovate updates.

That action requires a GitHub App (`isle-buildkit-renovate`) to be installed in the Islandora-Devops repo. This app is needed to generate an access token to allow renovate to create PRs for us in the GitHub workflow. During installation, the app was restricted to only this repo. This is all configurable in the GitHub UI by Islandora-Devops admins.

The action requires three secrets.

- The `GH_APP_INSTALLATION_ID` secret is the number found in the URL on [the GitHub Apps installation page for the Islandora-Devops org](https://github.com/organizations/Islandora-Devops/settings/installations) for the

- The two other secrets `GH_APP_ID` and `GH_APP_PRIV_KEY` can be found on [the GitHub App settings](https://github.com/organizations/Islandora-Devops/settings/apps/isle-buildkit-renovate)
- The value of `GH_APP_ID` is shown at the top of the page at the above URL
- The value of `GH_APP_PRIV_KEY` is a base64 encoded string of a private key created at the bottom of the page in the above UI. Creating a new key will download the key to your local machine. You can then generate the value needed by the GitHub Action by running e.g. `base64 -i ~/Downloads/isle-buildkit-renovate.2025-01-06.private-key.pem` and pasting that value into https://github.com/Islandora-Devops/isle-buildkit/settings/secrets/actions/GH_APP_PRIV_KEY. **This value is probably the only truly secret value out of the three**. If this value is ever exposed it should be rotated by deleting the existing private key and generating a new one.

##### Running renovate (manually for debugging)

First, generate a GitHub token. Instructions can be found at https://docs.renovatebot.com/modules/platform/github/#running-using-a-fine-grained-token

```
npm install -g renovate
Expand All @@ -555,8 +574,6 @@ export RENOVATE_ALLOWED_POST_UPGRADE_COMMANDS='["bash ci/update-sha.sh \"{{{depN
renovate --platform=github
```

Versions listed in GitHub tags or releases can use [advanced capture](https://docs.renovatebot.com/modules/manager/regex/#advanced-capture) in the Dockerfile to update the pinned version.


#### Updating Composer

Expand Down
43 changes: 43 additions & 0 deletions ci/fetch-app-token.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash

set -eou pipefail

if [[ $# -ne 3 ]]; then
echo "Usage: $0 <APP_ID> <INSTALL_ID> <PRIVATE_KEY_FILE_PATH>"
echo "e.g. ./ci/fetch-app-token.sh 123 456 /path/to/priv.pem"
exit 1
fi

APP_ID="$1"
INSTALL_ID="$2"
PRIVATE_KEY_FILE="$3"

if [[ ! -f "$PRIVATE_KEY_FILE" ]]; then
echo "Error: Private key file not found: $PRIVATE_KEY_FILE"
exit 1
fi

PRIVATE_KEY=$(cat "$PRIVATE_KEY_FILE")

NOW=$(date +%s)
# 5 minutes from now
EXPIRATION=$((NOW + 300))

JWT_HEADER=$(jq -n '{"alg":"RS256","typ":"JWT"}' | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')
JWT_PAYLOAD=$(jq -n --argjson iat "$NOW" --argjson exp "$EXPIRATION" --arg iss "$APP_ID" '{"iat":$iat,"exp":$exp,"iss":$iss}' | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')
JWT_SIGNATURE=$(echo -n "${JWT_HEADER}.${JWT_PAYLOAD}" | openssl dgst -sha256 -sign <(echo "$PRIVATE_KEY") | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')
JWT="${JWT_HEADER}.${JWT_PAYLOAD}.${JWT_SIGNATURE}"

RESPONSE=$(curl -s -X POST "https://api.github.com/app/installations/${INSTALL_ID}/access_tokens" \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github+json")

if echo "$RESPONSE" | jq -e '.token' > /dev/null; then
# this token has a TTL of 60m
# see https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app#generating-an-installation-access-token
echo "$RESPONSE" | jq -r '.token'
else
echo "Error:"
echo "$RESPONSE" | jq
exit 1
fi

0 comments on commit 3e38d8a

Please sign in to comment.