Repository navigation
115 lines (105 loc) · 4.78 KB
/
Copy pathpr-artifacts-description.yml
File metadata and controls
115 lines (105 loc) · 4.78 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
name: PR artifact links
on:
workflow_run:
workflows:
- CI
types:
- completed
permissions:
actions: read
contents: read
pull-requests: write
jobs:
description:
name: Add APK links to the pull request
if: >-
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 5
concurrency:
group: pr-apk-links-${{ github.event.workflow_run.pull_requests[0].number || github.event.workflow_run.id }}
cancel-in-progress: false
steps:
- name: Create or update the APK artifact description block
uses: actions/github-script@v9
with:
script: |
const run = context.payload.workflow_run;
const pullRequests = run.pull_requests || [];
if (pullRequests.length !== 1) {
core.notice(`Expected one pull request for workflow run ${run.id}, found ${pullRequests.length}`);
return;
}
const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRun, {
...context.repo, run_id: run.id, filter: 'latest', per_page: 100
});
if (jobs.some(job => job.name === 'Android tests and checks' && job.conclusion === 'skipped')) {
core.notice('Android checks were skipped by the change filter; no APK artifacts are expected');
return;
}
const pullNumber = pullRequests[0].number;
const expectedArtifacts = {
debug: `megaproxy-pr-${pullNumber}-debug-apk`,
release: `megaproxy-pr-${pullNumber}-unsigned-release-apk`,
};
const artifacts = await github.paginate(
github.rest.actions.listWorkflowRunArtifacts,
{
owner: context.repo.owner,
repo: context.repo.repo,
run_id: run.id,
per_page: 100,
}
);
const findArtifact = (name) => artifacts.find(
(artifact) => artifact.name === name && !artifact.expired
);
const debugArtifact = findArtifact(expectedArtifacts.debug);
const releaseArtifact = findArtifact(expectedArtifacts.release);
if (!debugArtifact || !releaseArtifact) {
core.setFailed(`Expected APK artifacts were not found for workflow run ${run.id}`);
return;
}
const artifactUrl = (artifact) =>
`${context.serverUrl}/${context.repo.owner}/${context.repo.repo}` +
`/actions/runs/${run.id}/artifacts/${artifact.id}`;
const marker = '<!-- megaproxy-pr-apks -->';
const body = [
marker,
`<!-- megaproxy-pr-apks-run: ${run.run_number}:${run.run_attempt || 1} -->`,
'## APK artifacts',
'',
`- [Download debug APK](${artifactUrl(debugArtifact)}) — signed with the disposable Android debug key`,
`- [Download unsigned release APK](${artifactUrl(releaseArtifact)}) — verified unsigned`,
'',
`Built from commit \`${run.head_sha.slice(0, 8)}\` by [CI run #${run.run_number}](${run.html_url}).`,
'Artifacts expire after 14 days. Neither APK uses the MegaProxy release key.',
'<!-- /megaproxy-pr-apks -->',
].join('\n');
const { data: pull } = await github.rest.pulls.get({
...context.repo, pull_number: pullNumber,
});
if (pull.state !== 'open' || pull.head.sha !== run.head_sha) {
core.notice('PR is closed or its head changed; keeping the existing description');
return;
}
const description = pull.body || '';
const previousRun = description.match(/<!-- megaproxy-pr-apks-run: (\d+):(\d+) -->/);
if (previousRun && (
Number(previousRun[1]) > run.run_number ||
(Number(previousRun[1]) === run.run_number && Number(previousRun[2]) > (run.run_attempt || 1))
)) {
core.notice('A newer CI run already published its artifacts');
return;
}
const block = /<!-- megaproxy-pr-apks -->[\s\S]*?<!-- \/megaproxy-pr-apks -->/g;
const authorBody = description.replace(block, '').trimEnd();
if (authorBody.includes(marker) || authorBody.includes('<!-- /megaproxy-pr-apks -->')) {
core.setFailed('Malformed APK block markers; refusing to overwrite the PR description');
return;
}
await github.rest.pulls.update({
...context.repo, pull_number: pullNumber,
body: authorBody ? `${authorBody}\n\n${body}` : body,
});