Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wide-pears-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"github-actions-cloudflare-pages": minor
---

feat: input pr-number
34 changes: 15 additions & 19 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@

name: deploy
on:
workflow_run:
workflows:
- test
types:
- completed
pull_request:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}

jobs:
fork:
if: ${{ github.event.pull_request.head.repo.fork }}
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- name: Fork PR notice
run: echo 'Fork pull request detected; skipping deploy job that requires repository secrets.'

deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch != 'main' }}
if: ${{ !github.event.pull_request.head.repo.fork }}
permissions:
actions: read
contents: read
Expand All @@ -22,19 +30,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- if: github.event_name == 'workflow_run'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
repository: ${{ github.event.workflow_run.head_repository.full_name }}
ref: ${{ github.event.workflow_run.head_sha }}
- if: github.event_name != 'workflow_run'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Get PR number
run: |
echo "PR Number: ${{ github.event.number }}"
- name: Get PR number other
run: |
echo "PR Number: ${{ github.event.pull_request.number }}"
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- id: 'cloudflare-pages'
uses: ./
with:
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ github-token:
github-environment:
description: 'GitHub environment to deploy to. You need to manually create this for the github repo'
required: true
pr-number:
description: 'GitHub pull request number to comment on. If not set, the action auto-detects from the event payload.'
required: false
working-directory:
description: 'Directory to run wrangler cli from'
required: false
Expand Down Expand Up @@ -136,7 +139,7 @@ jobs:

### Fork pull requests with `workflow_run`

When pull requests come from forks, the initial `pull_request` workflow may not have access to secrets. Use a second workflow triggered by `workflow_run` to deploy from the original repository context after approval.
When pull requests come from forks, the initial `pull_request` workflow may not have access to secrets. Use a second workflow triggered by `workflow_run` to deploy from the original repository context after approval, and set the `pr-number` input so the action can resolve the correct pull request to comment on.

```yaml
name: Deploy PR Preview (Fork Safe)
Expand Down Expand Up @@ -168,9 +171,10 @@ jobs:
directory: dist
github-token: ${{ secrets.GITHUB_TOKEN }}
github-environment: preview
pr-number: # The PR number
```

This action supports the `workflow_run` event and will use the `workflow_run` head commit SHA and branch for deployment metadata and PR comments.
This action supports the `workflow_run` event and will use the `workflow_run` head commit SHA and branch for deployment metadata.

## Comment Example

Expand Down
97 changes: 97 additions & 0 deletions __tests__/common/github/comment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
QueryPullRequestNodeIdByBranch
} from '@/common/github/comment.js'
import * as Context from '@/common/github/context.js'
import * as CommonInputs from '@/common/inputs.js'
import RESPONSE_DEPLOYMENTS from '@/responses/api.cloudflare.com/pages/deployments/deployments.response.json' with {type: 'json'}
import {setMockApi} from '@/tests/helpers/api.js'
import {EVENT_NAMES} from '@/types/github/workflow-events.js'
Expand Down Expand Up @@ -207,6 +208,102 @@ describe(addComment, () => {
})
})

describe('pr-number input', () => {
test('should use pr-number to resolve pull request node id', async () => {
expect.assertions(1)

vi.spyOn(CommonInputs, 'useCommonInputs').mockReturnValueOnce({
cloudflareApiToken: 'mock-cloudflare-api-token',
gitHubApiToken: 'mock-github-token',
gitHubEnvironment: undefined,
prNumber: '123',
wranglerVersion: 'mock-wrangler-version'
})

vi.spyOn(Context, 'useContextEvent').mockReturnValue({
eventName: 'workflow_dispatch',
payload: {}
} as Readonly<WorkflowEventExtract<'workflow_dispatch'>>)

vi.spyOn(Context, 'useContext').mockReturnValue({
event: {
eventName: 'workflow_dispatch',
payload: {} as never
},
repo: {
owner: 'andykenward',
repo: 'github-actions-cloudflare-pages',
node_id: 'repo_node_id'
},
branch: undefined,
sha: 'mock-github-sha',
graphqlEndpoint: 'https://api.github.com/graphql',
ref: 'refs/heads/feature-branch'
} as unknown as ReturnType<typeof Context.useContext>)

mockApi.interceptGithub(
{
query: QueryPullRequestNodeId,
variables: {
owner: 'andykenward',
repo: 'github-actions-cloudflare-pages',
number: 123
}
},
{
data: {
repository: {
pullRequest: {
id: 'MDExOlB1bGxSZXF1ZXN0Mjc5MTQ3NDM3'
}
}
}
}
)

mockApi.interceptGithub(
{
query: MutationAddComment,
variables: {
subjectId: 'MDExOlB1bGxSZXF1ZXN0Mjc5MTQ3NDM3',
body: '## Cloudflare Pages Deployment\n**Event Name:** workflow_dispatch\n**Environment:** production\n**Project:** cloudflare-pages-action\n**Built with commit:** mock-github-sha\n**Preview URL:** https://206e215c.cloudflare-pages-action-a5z.pages.dev\n**Branch Preview URL:** https://unknown-branch.cloudflare-pages-action-a5z.pages.dev\n\n### Wrangler Output\nsuccess'
}
},
{
data: {
addComment: {
commentEdge: {
node: {
id: '1'
}
}
}
}
}
)

const comment = await addComment(mockData, 'success')

expect(comment).toBe('1')
})

test('should throw for invalid pr-number input', async () => {
expect.assertions(1)

vi.spyOn(CommonInputs, 'useCommonInputs').mockReturnValueOnce({
cloudflareApiToken: 'mock-cloudflare-api-token',
gitHubApiToken: 'mock-github-token',
gitHubEnvironment: undefined,
prNumber: 'abc',
wranglerVersion: 'mock-wrangler-version'
})

await expect(addComment(mockData, 'success')).rejects.toThrow(
'Invalid pr-number input: abc'
)
})
})

describe('eventName: workflow_dispatch', () => {
test('should add comment', async () => {
expect.assertions(1)
Expand Down
2 changes: 2 additions & 0 deletions __tests__/common/inputs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe('common', () => {
cloudflareApiToken: 'mock-cloudflare-api-token',
gitHubApiToken: 'mock-github-token',
gitHubEnvironment: 'mock-github-environment',
prNumber: undefined,
wranglerVersion: 'mock-wrangler-version'
})
})
Expand All @@ -71,6 +72,7 @@ describe('common', () => {
cloudflareApiToken: 'mock-cloudflare-api-token',
gitHubApiToken: 'mock-github-token',
gitHubEnvironment: undefined,
prNumber: undefined,
wranglerVersion: packageJson.devDependencies.wrangler
})
})
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ inputs:
github-environment:
description: 'GitHub environment to deploy to. You need to manually create this for the github repo'
required: true
pr-number:
description: 'GitHub pull request number to comment on. If not set, the action auto-detects from the event payload.'
required: false
working-directory:
description: 'Directory to run wrangler cli from'
required: false
Expand Down
Loading
Loading