-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaction.yml
More file actions
83 lines (71 loc) · 2.8 KB
/
Copy pathaction.yml
File metadata and controls
83 lines (71 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
name: Setup GitHub app access key
description: Generate a valid access key for a given repo based on a GitHub app
inputs:
app_id:
description: GitHub application id
required: true
app_key:
description: GitHub application secret key
required: true
repo:
description: GitHub repo path (org/repo)
required: true
outputs:
access_token:
description: GitHub access token
value: ${{ steps.gh_app_installation.outputs.access_token }}
runs:
using: "composite"
steps:
- name: Generate JWT and get installation access token
id: gh_app_installation
uses: actions/github-script@v7
env:
APP_KEY: ${{ inputs.app_key }}
APP_ID: ${{ inputs.app_id }}
REPO: ${{ inputs.repo }}
with:
script: |
const crypto = require('crypto');
const appKey = Buffer.from(process.env.APP_KEY.trim(), 'base64').toString('utf8');
const appId = process.env.APP_ID.trim();
const repo = process.env.REPO.trim();
core.setSecret(process.env.APP_KEY);
// Build JWT (RS256)
const b64url = (data) =>
Buffer.from(data).toString('base64')
.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
const now = Math.floor(Date.now() / 1000);
const header = b64url(JSON.stringify({ alg: 'RS256', typ: 'JWT' }));
const payload = b64url(JSON.stringify({ iss: parseInt(appId, 10), iat: now - 60, exp: now + 600 }));
const content = `${header}.${payload}`;
const signer = crypto.createSign('RSA-SHA256');
signer.update(content);
const jwt = `${content}.${b64url(signer.sign(appKey))}`;
core.setSecret(jwt);
const headers = {
Authorization: `Bearer ${jwt}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
};
// Get installation ID
const installRes = await fetch(`https://api.github.com/repos/${repo}/installation`, { headers });
if (!installRes.ok) {
const body = await installRes.text();
core.setFailed(`Failed to get installation for ${repo}: ${body}`);
return;
}
const { id: installationId } = await installRes.json();
// Exchange for access token
const tokenRes = await fetch(
`https://api.github.com/app/installations/${installationId}/access_tokens`,
{ method: 'POST', headers },
);
if (!tokenRes.ok) {
const body = await tokenRes.text();
core.setFailed(`Failed to get access token: ${body}`);
return;
}
const { token } = await tokenRes.json();
core.setSecret(token);
core.setOutput('access_token', token);