Skip to content

Commit d33fcc1

Browse files
ctcpipwesleytodd
andauthored
fix(test): 💚 fix CI runs for fork PRs (#240)
fork PRs targeting main will never be able to pass integration tests or action-in-action due to the lack of permissions that fork action/workflow get: - it will not have write permission on the main repo - it will not have write permission on the wesleytodd/meeting-maker repo - it will not have write permission on its own repo because it's running in the main repo context therefore, if you want to see the integration tests and action-in-action test passing, then a PR needs to be created in the fork repo Co-authored-by: Wes Todd <[email protected]>
1 parent a51eb35 commit d33fcc1

File tree

3 files changed

+58
-14
lines changed

3 files changed

+58
-14
lines changed

‎.github/workflows/test.yml‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ jobs:
2727

2828
testint:
2929
runs-on: ubuntu-latest
30+
# only run if not a fork PR targeting main repo due to permissions
31+
if: ${{ !(github.head_repo || github.event.pull_request.head.repo) || github.repository == (github.head_repo.full_name || github.event.pull_request.head.repo.full_name) }}
3032
steps:
3133
- uses: actions/checkout@v4
3234
- name: Use Node.js 24
@@ -36,9 +38,13 @@ jobs:
3638
- run: npm install
3739
- run: npm run test:integration
3840
env:
39-
GITHUB_TOKEN: ${{ secrets.INT_TEST_TOKEN }}
41+
GITHUB_TOKEN: ${{ secrets.INT_TEST_TOKEN != '' && secrets.INT_TEST_TOKEN || secrets.GITHUB_TOKEN }}
42+
GITHUB_REPOSITORY: ${{ github.repository }}
43+
GITHUB_HEAD_REPO: ${{ github.head_repo && github.head_repo.full_name || github.event.pull_request.head.repo.full_name || '' }}
4044
action-in-action:
4145
runs-on: ubuntu-latest
46+
# only run if not a fork PR targeting main repo due to permissions
47+
if: ${{ !(github.head_repo || github.event.pull_request.head.repo) || github.repository == (github.head_repo.full_name || github.event.pull_request.head.repo.full_name) }}
4248
steps:
4349
- uses: actions/checkout@v4
4450
- name: Use Node.js 24
@@ -48,6 +54,9 @@ jobs:
4854
- run: npm install
4955
- uses: ./
5056
id: maker
57+
env:
58+
TEST_REPOS: ${{ github.repository != 'pkgjs/meet' && github.repository || 'pkgjs/meet,pkgjs/meet' }}
59+
TEST_ORGS: ${{ github.repository != 'pkgjs/meet' && '' || 'pkgjs' }}
5160
with:
5261
token: ${{ secrets.GITHUB_TOKEN }}
5362
schedules: 2020-04-02T17:00:00.0Z/P1D
@@ -57,7 +66,7 @@ jobs:
5766
agendaLabel: meeting-agenda-test
5867
meetingLink: https://github.com/pkgjs/meet
5968
createNotes: true
60-
repos: pkgjs/meet,pkgjs/meet
61-
orgs: pkgjs
69+
repos: ${{ env.TEST_REPOS }}
70+
orgs: ${{ env.TEST_ORGS }}
6271
- name: clean up issue
6372
run: node ./test/_close-issue.js ${{ secrets.GITHUB_TOKEN }} ${{ steps.maker.outputs.issueNumber }}

‎test/_close-issue.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ const issues = require('../lib/issues')
66
if (!issueNumber) {
77
return
88
}
9-
console.log(`Closing test issue ${issueNumber}`)
109

1110
const client = getOctokit(token)
11+
const repo = context.repo
12+
13+
console.log(`Closing test issue ${issueNumber} in ${repo.owner}/${repo.repo}`)
14+
1215
await issues.closeIssue(client, issueNumber, {
13-
...context.repo
16+
...repo
1417
})
1518
})(process.argv)

‎test/integration.js‎

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,47 @@ const { getOctokit } = require('@actions/github')
1111
const pkg = require('../package.json')
1212
const meetings = require('../lib/meetings')
1313

14+
const mainRepo = 'pkgjs/meet'
15+
16+
function getTestRepo () {
17+
let testRepo = { owner: 'wesleytodd', repo: 'meeting-maker' } // ✨ Wes, the meeting maker ✨
18+
19+
if (process.env.GITHUB_REPOSITORY) {
20+
// we appear to be in a GH action
21+
if (process.env.GITHUB_REPOSITORY !== mainRepo) {
22+
// action running in a fork
23+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/')
24+
testRepo = { owner, repo }
25+
} else if (process.env.GITHUB_HEAD_REPO &&
26+
process.env.GITHUB_HEAD_REPO !== mainRepo) {
27+
// action running in a fork PR targeting main repo
28+
// skip tests - GH token doesn't have write permissions for either repo
29+
throw new Error('skipping integration tests: fork PR targeting main repo (no permissions)')
30+
}
31+
}
32+
33+
console.log(`using repository ${testRepo.owner}/${testRepo.repo}`)
34+
return testRepo
35+
}
36+
1437
suite(`${pkg.name} integration`, () => {
1538
let client
39+
let testRepo
40+
1641
before(() => {
17-
client = getOctokit(process.env.GITHUB_TOKEN)
42+
const token = process.env.GITHUB_TOKEN
43+
if (!token) {
44+
throw new Error('GITHUB_TOKEN environment variable is required for integration tests')
45+
}
46+
47+
client = getOctokit(token)
48+
testRepo = getTestRepo()
1849
})
50+
1951
test('should create next meeting issue', async () => {
2052
const issue = await meetings.shouldCreateNextMeetingIssue(client, {
21-
owner: 'wesleytodd',
22-
repo: 'meeting-maker',
53+
owner: testRepo.owner,
54+
repo: testRepo.repo,
2355
issueTitle: ({ date }) => `Test Meeting ${date.toZonedDateTimeISO('UTC').toPlainDate().toString()}`,
2456
createWithin: 'P7D',
2557
agendaLabel: 'meeting-agenda',
@@ -30,8 +62,8 @@ suite(`${pkg.name} integration`, () => {
3062
now: Temporal.Instant.from('2020-04-13T13:00:00.0Z'),
3163
meetingLabels: ['testMeeting', 'test']
3264
})
33-
assert.deepStrictEqual(issue.owner, 'wesleytodd')
34-
assert.deepStrictEqual(issue.repo, 'meeting-maker')
65+
assert.deepStrictEqual(issue.owner, testRepo.owner)
66+
assert.deepStrictEqual(issue.repo, testRepo.repo)
3567
assert.deepStrictEqual(issue.title, `Test Meeting ${Temporal.Instant.from('2020-04-16T13:00:00.0Z').toZonedDateTimeISO('UTC').toPlainDate().toString()}`)
3668
assert.deepStrictEqual(issue.agendaLabel, 'meeting-agenda')
3769
assert.deepStrictEqual(issue.labels, ['testMeeting', 'test'])
@@ -41,8 +73,8 @@ suite(`${pkg.name} integration`, () => {
4173

4274
test('create next meeting issue', async () => {
4375
const issue = await meetings.createNextMeeting(client, {
44-
owner: 'wesleytodd',
45-
repo: 'meeting-maker',
76+
owner: testRepo.owner,
77+
repo: testRepo.repo,
4678
createWithin: 'P7D',
4779
schedules: [
4880
// 5pm GMT April 2 repeating every 28 days
@@ -60,8 +92,8 @@ suite(`${pkg.name} integration`, () => {
6092
assert.deepStrictEqual(issue.data.state, 'open')
6193

6294
await client.rest.issues.update({
63-
owner: 'wesleytodd',
64-
repo: 'meeting-maker',
95+
owner: testRepo.owner,
96+
repo: testRepo.repo,
6597
issue_number: issue.data.number,
6698
state: 'closed'
6799
})

0 commit comments

Comments
 (0)