Skip to content

Commit 09ec165

Browse files
authored
Merge pull request #32 from git-for-windows/deal-with-expired-installation-access-token
Deal with expired installation access tokens
2 parents 2e4429f + 65cc743 commit 09ec165

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
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 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 }}',

.github/workflows/create-azure-self-hosted-runners.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
)
8181
8282
const getInstallationAccessToken = require('./get-installation-access-token')
83-
const accessToken = await getInstallationAccessToken(
83+
const { token: accessToken } = await getInstallationAccessToken(
8484
console,
8585
appId,
8686
privateKey,

get-installation-access-token.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ module.exports = async (context, appId, privateKey, installation_id) => {
77
'POST',
88
`/app/installations/${installation_id}/access_tokens`)
99
if (answer.error) throw answer.error
10-
if (answer.token) return answer.token
10+
if (answer.token) return {
11+
expiresAt: answer.expires_at,
12+
token: answer.token
13+
}
1114
throw new Error(`Unhandled response:\n${JSON.stringify(answer, null, 2)}`)
1215
}

0 commit comments

Comments
 (0)