Created
June 12, 2023 11:20
-
-
Save sdjnes/7b94876b23d45cfe8d57982c9472cd3a to your computer and use it in GitHub Desktop.
NX Set SHAs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Octokit } = require('@octokit/action'); | |
const core = require('@actions/core'); | |
const github = require('@actions/github'); | |
const { execSync } = require('child_process'); | |
const { | |
runId, | |
repo: { repo, owner }, | |
eventName, | |
} = github.context; | |
const [ | |
_node, | |
_filename, | |
githubToken, | |
baseBranchName, | |
branchName, | |
lastSuccessfulEvent, | |
headSha, | |
] = process.argv; | |
process.env.GITHUB_TOKEN = githubToken; | |
(async () => { | |
process.stdout.write(JSON.stringify(process.argv)); | |
const HEAD_SHA = | |
headSha || execSync(`git rev-parse HEAD`, { encoding: 'utf-8' }).toString(); | |
let BASE_SHA = await findSuccessfulCommit( | |
runId, | |
owner, | |
repo, | |
baseBranchName, | |
branchName, | |
lastSuccessfulEvent | |
); | |
// If no successful workflow run is found, use the branching point from the base branch | |
if (BASE_SHA) { | |
process.stdout.write(` | |
\n | |
Found successful run for this workflow. Using it as BASE_SHA | |
\n | |
`); | |
} else { | |
BASE_SHA = execSync( | |
`git merge-base origin/${baseBranchName} ${HEAD_SHA}` | |
).toString(); | |
process.stdout.write(` | |
\n | |
No successful run for this workflow found on the branch ${branchName}.\n | |
Using the branching point between origin/${baseBranchName} and this branch's head ${HEAD_SHA}\n | |
BASE_SHA=${BASE_SHA} | |
\n | |
`); | |
} | |
const stripNewLineEndings = (sha) => sha.replace('\n', ''); | |
core.setOutput('base', stripNewLineEndings(BASE_SHA)); | |
core.setOutput('head', stripNewLineEndings(HEAD_SHA)); | |
})(); | |
async function findSuccessfulCommit( | |
run_id, | |
owner, | |
repo, | |
baseBranchName, | |
branchName, | |
lastSuccessfulEvent | |
) { | |
const octokit = new Octokit(); | |
const workflowId = await octokit | |
.request(`GET /repos/${owner}/${repo}/actions/runs/${run_id}`, { | |
owner, | |
repo, | |
branch: baseBranchName, | |
run_id, | |
}) | |
.then(({ data: { workflow_id } }) => workflow_id); | |
const shas = await octokit | |
.request( | |
`GET /repos/${owner}/${repo}/actions/workflows/${workflowId}/runs`, | |
{ | |
owner, | |
repo, | |
branch: branchName, | |
workflowId, | |
event: lastSuccessfulEvent, | |
status: 'success', | |
} | |
) | |
.then(({ data: { workflow_runs } }) => | |
workflow_runs.map((run) => run.head_sha) | |
); | |
return await findExistingCommit(shas); | |
} | |
/** | |
* Get first existing commit | |
* @param {string[]} commit_shas | |
* @returns {string?} | |
*/ | |
async function findExistingCommit(shas) { | |
for (const commitSha of shas) { | |
if (await commitExists(commitSha)) { | |
return commitSha; | |
} | |
} | |
return undefined; | |
} | |
/** | |
* Check if given commit is valid | |
* @param {string} commitSha | |
* @returns {boolean} | |
*/ | |
async function commitExists(commitSha) { | |
try { | |
execSync(`git cat-file -e ${commitSha}`, { stdio: ['pipe', 'pipe', null] }); | |
return true; | |
} catch { | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment