Skip to content

Commit 65cc743

Browse files
committed
build-and-deploy: refresh the installation access token as needed
The build https://github.com/git-for-windows/git-for-windows-automation/actions/runs/4153007326/jobs/7184357891 as well the build https://github.com/git-for-windows/git-for-windows-automation/actions/runs/4153007483/jobs/7184358147 failed due to an expiring installation access token: these tokens expire after an hour, and the step that built the Pacman package took well over an hour. To cope with that, remember the expiry date of the token, and after the Pacman package has been built, refresh it if it is expired (or running the danger of expiring while the packages are deployed). Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 36a514b commit 65cc743

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

.github/workflows/build-and-deploy.yml

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ jobs:
6666
)
6767
6868
const getInstallationAccessToken = require('./get-installation-access-token')
69-
const { token: accessToken } = await getInstallationAccessToken(
69+
const { expiresAt, token: accessToken } = await getInstallationAccessToken(
7070
console,
7171
appId,
7272
privateKey,
7373
installationId
7474
)
7575
7676
core.setSecret(accessToken)
77+
core.setOutput('expires-at', expiresAt)
7778
core.setOutput('token', accessToken)
7879
7980
- name: get check run id
@@ -295,6 +296,45 @@ jobs:
295296
exit 1
296297
fi
297298
299+
- name: refresh installation token (if needed)
300+
if: env.CREATE_CHECK_RUN != 'false'
301+
id: refresh
302+
uses: actions/github-script@v6
303+
with:
304+
script: |
305+
// GitHub Apps' installation access tokens expire after one hour, see:
306+
// https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-an-installation
307+
// let's generate a new one if less than 5 minutes before the expiry date, otherwise reuse it
308+
if (Date.parse('${{ steps.setup.outputs.expires-at }}') - Date.now() > 5 * 60 * 1000) {
309+
core.setOutput('expires-at', '${{ steps.setup.outputs.expires-at }}')
310+
core.setOutput('token', '${{ steps.setup.outputs.token }}')
311+
core.info('Continuing to use the unexpired installation access token')
312+
return
313+
}
314+
const appId = ${{ secrets.GH_APP_ID }}
315+
const privateKey = `${{ secrets.GH_APP_PRIVATE_KEY }}`
316+
317+
const getAppInstallationId = require('./get-app-installation-id')
318+
const installationId = await getAppInstallationId(
319+
console,
320+
appId,
321+
privateKey,
322+
process.env.OWNER,
323+
process.env.REPO
324+
)
325+
326+
const getInstallationAccessToken = require('./get-installation-access-token')
327+
const { expiresAt, token: accessToken } = await getInstallationAccessToken(
328+
console,
329+
appId,
330+
privateKey,
331+
installationId
332+
)
333+
334+
core.setSecret(accessToken)
335+
core.setOutput('expires-at', expiresAt)
336+
core.setOutput('token', accessToken)
337+
298338
- name: update check-run
299339
if: env.CREATE_CHECK_RUN != 'false'
300340
uses: actions/github-script@v6
@@ -303,7 +343,7 @@ jobs:
303343
const updateCheckRun = require('./update-check-run')
304344
await updateCheckRun(
305345
console,
306-
'${{ steps.setup.outputs.token }}',
346+
'${{ steps.refresh.outputs.token }}',
307347
process.env.OWNER,
308348
process.env.REPO,
309349
'${{ steps.check-run.outputs.id }}',
@@ -347,7 +387,7 @@ jobs:
347387
const updateCheckRun = require('./update-check-run')
348388
await updateCheckRun(
349389
console,
350-
'${{ steps.setup.outputs.token }}',
390+
'${{ steps.refresh.outputs.token }}',
351391
process.env.OWNER,
352392
process.env.REPO,
353393
'${{ steps.check-run.outputs.id }}',

get-installation-access-token.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = async (context, appId, privateKey, installation_id) => {
88
`/app/installations/${installation_id}/access_tokens`)
99
if (answer.error) throw answer.error
1010
if (answer.token) return {
11+
expiresAt: answer.expires_at,
1112
token: answer.token
1213
}
1314
throw new Error(`Unhandled response:\n${JSON.stringify(answer, null, 2)}`)

0 commit comments

Comments
 (0)