Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(surge-preview): add support of workflow_run event #131

Merged
merged 6 commits into from
Apr 24, 2024
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
72 changes: 69 additions & 3 deletions packages/surge-preview-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ It helps detecting if the `surge-preview` action can/should be run:

The action provides outputs that let manage such use cases.

Limitations
- for Pull Request only
Work with workflow triggered by the following events:
- `pull_request`
- `workflow_run`

## Usage

See [action.yml](./action.yml) for inputs and outputs.


### `pull_request` event

In the following, the outputs of the `surge-preview-tools` action are used to decide if the `surge-preview` action can run.

```yaml
Expand Down Expand Up @@ -56,7 +60,69 @@ jobs:
uses: afc163/surge-preview@v1
with:
surge_token: ${{ secrets.SURGE_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
dist: site
failOnError: true
teardown: true
build: |
ls -lh site
```

### `workflow_run` event

In the following, the outputs of the `surge-preview-tools` action are used to decide if the `surge-preview` action can run.

**Note**:
- the `surge-preview-tools` action supports `workflow_run` event as of version 3.2.0.
- the `surge-preview` action supports `workflow_run` event as of [version 1.8.0](https://github.com/afc163/surge-preview/commit/4628aab4d29c2679cbce5aff7f45eac8ff219609).

When running the `surge-preview-tools` action in a workflow triggered by `workflow_run` event, the following permissions must be granted to the `GITHUB_TOKEN`:
- metadata: read
- pull-requests: read


```yaml
name: Surge PR Preview - Deploy Stage

on:
workflow_run:
workflows: ["Surge PR Preview - Build Stage"] # The name of the workflow that will trigger this workflow
types:
- completed

jobs:
# MUST be unique across all surge preview deployments for a repository as the job id is used in the deployment URL
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }}

permissions:
# This permission is only required by surge-preview when it is configured to create Pull Request comment
pull-requests: write

steps:
- uses: bonitasoft/actions/packages/surge-preview-tools@TAGNAME
id: surge-preview-tools
with:
surge-token: ${{ secrets.SURGE_TOKEN }}
- name: Echo surge preview tools output
run: |
echo "can-run-surge-command: ${{ steps.surge-preview-tools.outputs.can-run-surge-command }}"
echo "domain-exist: ${{ steps.surge-preview-tools.outputs.domain-exist }}"
echo "preview-url: ${{ steps.surge-preview-tools.outputs.preview-url }}"
echo "surge-token-valid: ${{ steps.surge-preview-tools.outputs.surge-token-valid }}"

- name: Download the site previously built
uses: dawidd6/action-download-artifact@v3
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: pr-build-dist # must be kept in sync with the artifact name downloaded in the build stage
path: site/

- name: Publish Demo preview
if: steps.surge-preview-tools.outputs.can-run-surge-command == 'true'
uses: afc163/surge-preview@v1
with:
surge_token: ${{ secrets.SURGE_TOKEN }}
dist: site
failOnError: true
teardown: true
Expand Down
4 changes: 4 additions & 0 deletions packages/surge-preview-tools/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ inputs:
surge-token:
description: 'surge.sh token'
required: false
github-token:
description: 'Github token'
required: false
default: ${{ github.token }}

outputs:
can-run-surge-command:
Expand Down
53 changes: 48 additions & 5 deletions packages/surge-preview-tools/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4886,6 +4886,7 @@ const statusCodeCacheableByDefault = new Set([
206,
300,
301,
308,
404,
405,
410,
Expand Down Expand Up @@ -4958,10 +4959,10 @@ function parseCacheControl(header) {

// TODO: When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives),
// the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale
const parts = header.trim().split(/\s*,\s*/); // TODO: lame parsing
const parts = header.trim().split(/,/);
for (const part of parts) {
const [k, v] = part.split(/\s*=\s*/, 2);
cc[k] = v === undefined ? true : v.replace(/^"|"$/g, ''); // TODO: lame unquoting
const [k, v] = part.split(/=/, 2);
cc[k.trim()] = v === undefined ? true : v.trim().replace(/^"|"$/g, '');
}

return cc;
Expand Down Expand Up @@ -13459,11 +13460,53 @@ __nccwpck_require__.r(__webpack_exports__);


try {
/**
* Retrieve the PR number
* Inspired by https://github.com/afc163/surge-preview/blob/main/src/main.ts
* @returns prNumber
*/
const getPrNumber = async (github_context) => {
const token = _actions_core__WEBPACK_IMPORTED_MODULE_0__.getInput('github-token', { required: true });
const octokit = _actions_github__WEBPACK_IMPORTED_MODULE_1__.getOctokit(token);
const {payload} = github_context;
const gitCommitSha =
payload?.pull_request?.head?.sha ||
payload?.workflow_run?.head_sha;

if (payload.number && payload.pull_request) {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`prNumber retrieved from pull_request ${payload.number}`);
return payload.number;
} else {
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug('Not a pull_request, so doing a API search');
// Inspired by https://github.com/orgs/community/discussions/25220#discussioncomment-8697399
const query = {
q: `repo:${github_context.repo.owner}/${github_context.repo.repo} is:pr sha:${gitCommitSha}`,
per_page: 1,
};
try {
const result = await octokit.rest.search.issuesAndPullRequests(query);
const pr = result.data.items.length > 0 && result.data.items[0];
_actions_core__WEBPACK_IMPORTED_MODULE_0__.debug(`Found related pull_request: ${JSON.stringify(pr, null, 2)}`);
return pr ? pr.number : undefined;
} catch (e) {
// As mentioned in https://github.com/orgs/community/discussions/25220#discussioncomment-8971083
// from time to time, you may get rate limit errors given search API seems to use many calls internally.
_actions_core__WEBPACK_IMPORTED_MODULE_0__.warning(`Unable to get the PR number with API search: ${e}`);
}
}
}

const surgeCliVersion = (0,_surge_utils__WEBPACK_IMPORTED_MODULE_2__/* .getSurgeCliVersion */ .re)();
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Surge cli version: ${surgeCliVersion}`);

const {job, payload} = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context;
const prNumber= await getPrNumber(_actions_github__WEBPACK_IMPORTED_MODULE_1__.context);
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Find PR number: ${prNumber}`);
if(prNumber === undefined){
_actions_core__WEBPACK_IMPORTED_MODULE_0__.setFailed('No PR number found');
}

const payload = _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.payload;
const domain = (0,_utils_mjs__WEBPACK_IMPORTED_MODULE_3__/* .computeSurgeDomain */ .wp)(_actions_github__WEBPACK_IMPORTED_MODULE_1__.context.repo, _actions_github__WEBPACK_IMPORTED_MODULE_1__.context.job, payload.number);
const domain = (0,_utils_mjs__WEBPACK_IMPORTED_MODULE_3__/* .computeSurgeDomain */ .wp)(_actions_github__WEBPACK_IMPORTED_MODULE_1__.context.repo, job, prNumber);
const previewUrl = `https://${domain}`;
_actions_core__WEBPACK_IMPORTED_MODULE_0__.setOutput('preview-url', previewUrl);
_actions_core__WEBPACK_IMPORTED_MODULE_0__.info(`Computed preview url: ${previewUrl}`);
Expand Down
Loading
Loading