Skip to content

Commit

Permalink
feat: [CYCLOUD-1447] Auto-detect PR numbers (#1009)
Browse files Browse the repository at this point in the history
* WIP - need to ask for ideal way to check existing variables

* check for existing variables

* consolidate comments

* remove yarn lock file

* run commands from PR feedback

* logging for testing purposes only

* more logging

* more logging

* simplify URL logic

* more logging

* remove logging - fix url string

* log response for fallback logic

* docs: rewrite readme working directory description (#1005)

* chore(deps): update dependency @types/node to v20.5.7 (#1008)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* docs: rework requirements for contributors (#1010)

* feat(deps): update cypress to 13.0.0 (#1012)

* logging for testing purposes only

* test: run component test example from current branch (#1013)

* more logging

* more logging

* simplify URL logic

* more logging

* remove logging - fix url string

* log response for fallback logic

* cleanup

* doc update

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

* exit detectPrNumber if variables already defined

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

* docs update - formatting fix for readability

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

* try catch pr data request

* Readme update

* Update README.md

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>

---------

Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 1, 2023
1 parent fd50b62 commit 7215fc1
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,47 @@ jobs:
publish-summary: false
```

### Automatic PR number & URL detection

When recording runs to Cypress Cloud, the PR number and URL can be automatically detected if you pass `GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`
via the workflow `env`. When set, this value enables the Action to perform additional logic that grabs the related PR number and URL (if they
exist) and sets them in the environment variables `CYPRESS_PULL_REQUEST_ID` and `CYPRESS_PULL_REQUEST_URL`, respectively.
* See Cypress' documentation on [CI Build Information](https://on.cypress.io/guides/continuous-integration/introduction#CI-Build-Information)

Example workflow using the variables:
```yml
name: Example echo PR number and URL
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v6
with:
record: true
- run: echo "PR number is $CYPRESS_PULL_REQUEST_ID"
- run: echo "PR URL is $CYPRESS_PULL_REQUEST_URL"
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

#### Triggering event: `pull_request`/`pull_request_target`

For either of these events, we set `CYPRESS_PULL_REQUEST_ID` and `CYPRESS_PULL_REQUEST_URL` to that of the PR number and URL, respectively, of the
PR that triggered the workflow.

#### Triggering event: `push`

When a commit on a branch without a PR is made, the Cypress GitHub Action checks to see if the commit that triggered the workflow has a
related PR. If the commit exists in any other PRs, it's considered a related PR. When there are related PRs, we grab the first related PR
and use that PR's number and URL for `CYPRESS_PULL_REQUEST_ID` and `CYPRESS_PULL_REQUEST_URL`, respectively.

If no related PR is detected, `CYPRESS_PULL_REQUEST_ID` and `CYPRESS_PULL_REQUEST_URL` will be undefined.

## Node.js

### Support
Expand Down
76 changes: 76 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74832,6 +74832,80 @@ const waitOnMaybe = () => {

const I = (x) => x

const detectPrNumber = async () => {
const {
GITHUB_SHA,
GITHUB_TOKEN,
GITHUB_RUN_ID,
GITHUB_REPOSITORY,
GITHUB_HEAD_REF,
GITHUB_REF,
GITHUB_SERVER_URL,
CYPRESS_PULL_REQUEST_ID,
CYPRESS_PULL_REQUEST_URL
} = process.env

if (CYPRESS_PULL_REQUEST_ID && CYPRESS_PULL_REQUEST_URL) {
// Both pull request envs are already defined - no need to do anything else
return
}

const [owner, repo] = GITHUB_REPOSITORY.split('/')
let prNumber

if (GITHUB_TOKEN) {
debug(
`Detecting PR number by asking GitHub about run ${GITHUB_RUN_ID}`
)

const client = new Octokit({
auth: GITHUB_TOKEN
})

if (GITHUB_HEAD_REF) {
// GITHUB_HEAD_REF is only defined when the event that triggered it was 'pull_request' or 'pull_request_target' (meaning a PR number should be readily-available)
// should have format refs/pull/<pr_number>/merge when triggered by pull_request workflow
prNumber = parseInt(GITHUB_REF.split('/')[2])
} else {
try {
const resp = await client.request(
'GET /repos/:owner/:repo/commits/:commit_sha/pulls',
{
owner,
repo,
commit_sha: GITHUB_SHA
}
)

if (
resp &&
resp.data &&
resp.data[0] &&
resp.data[0].number
) {
prNumber = resp.data[0].number
}
} catch (e) {
console.error(
`Unable to fetch related PR data for commit: '${GITHUB_SHA}': `,
e
)
}
}

if (prNumber) {
if (!CYPRESS_PULL_REQUEST_ID) {
core.exportVariable('CYPRESS_PULL_REQUEST_ID', prNumber)
}

const url = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/${prNumber}`
if (!CYPRESS_PULL_REQUEST_URL) {
core.exportVariable('CYPRESS_PULL_REQUEST_URL', url)
}
}
}
}

/**
* Asks Cypress API if there were already builds for this commit.
* In that case increments the count to get unique parallel id.
Expand Down Expand Up @@ -75065,6 +75139,8 @@ const runTests = async () => {
core.exportVariable('CYPRESS_CACHE_FOLDER', CYPRESS_CACHE_FOLDER)
core.exportVariable('TERM', 'xterm')

await detectPrNumber()

if (customCommand) {
console.log('Using custom test command: %s', customCommand)
return execCommand(customCommand, true, 'run tests')
Expand Down
76 changes: 76 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,80 @@ const waitOnMaybe = () => {

const I = (x) => x

const detectPrNumber = async () => {
const {
GITHUB_SHA,
GITHUB_TOKEN,
GITHUB_RUN_ID,
GITHUB_REPOSITORY,
GITHUB_HEAD_REF,
GITHUB_REF,
GITHUB_SERVER_URL,
CYPRESS_PULL_REQUEST_ID,
CYPRESS_PULL_REQUEST_URL
} = process.env

if (CYPRESS_PULL_REQUEST_ID && CYPRESS_PULL_REQUEST_URL) {
// Both pull request envs are already defined - no need to do anything else
return
}

const [owner, repo] = GITHUB_REPOSITORY.split('/')
let prNumber

if (GITHUB_TOKEN) {
debug(
`Detecting PR number by asking GitHub about run ${GITHUB_RUN_ID}`
)

const client = new Octokit({
auth: GITHUB_TOKEN
})

if (GITHUB_HEAD_REF) {
// GITHUB_HEAD_REF is only defined when the event that triggered it was 'pull_request' or 'pull_request_target' (meaning a PR number should be readily-available)
// should have format refs/pull/<pr_number>/merge when triggered by pull_request workflow
prNumber = parseInt(GITHUB_REF.split('/')[2])
} else {
try {
const resp = await client.request(
'GET /repos/:owner/:repo/commits/:commit_sha/pulls',
{
owner,
repo,
commit_sha: GITHUB_SHA
}
)

if (
resp &&
resp.data &&
resp.data[0] &&
resp.data[0].number
) {
prNumber = resp.data[0].number
}
} catch (e) {
console.error(
`Unable to fetch related PR data for commit: '${GITHUB_SHA}': `,
e
)
}
}

if (prNumber) {
if (!CYPRESS_PULL_REQUEST_ID) {
core.exportVariable('CYPRESS_PULL_REQUEST_ID', prNumber)
}

const url = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/${prNumber}`
if (!CYPRESS_PULL_REQUEST_URL) {
core.exportVariable('CYPRESS_PULL_REQUEST_URL', url)
}
}
}
}

/**
* Asks Cypress API if there were already builds for this commit.
* In that case increments the count to get unique parallel id.
Expand Down Expand Up @@ -669,6 +743,8 @@ const runTests = async () => {
core.exportVariable('CYPRESS_CACHE_FOLDER', CYPRESS_CACHE_FOLDER)
core.exportVariable('TERM', 'xterm')

await detectPrNumber()

if (customCommand) {
console.log('Using custom test command: %s', customCommand)
return execCommand(customCommand, true, 'run tests')
Expand Down

0 comments on commit 7215fc1

Please sign in to comment.