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(action): fallback sha option #152

Merged
merged 1 commit into from
May 23, 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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ jobs:
# Default: false
error-on-no-successful-workflow: ""

# Fallback SHA to use if no successful workflow run is found. This can be useful in scenarios where you need a specific commit as a reference for comparison, especially in newly set up repositories or those with sparse workflow runs.
#
# Default: ""
fallback-sha: ""

# The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc.
#
# Default: push
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ inputs:
error-on-no-successful-workflow:
description: "By default, if no successful workflow is found on the main branch to determine the SHA, we will log a warning and use HEAD~1. Enable this option to error and exit instead."
default: "false"
fallback-sha:
description: "Fallback SHA to use if no successful workflow run is found."
required: false
default: ""
last-successful-event:
description: "The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc"
default: "push"
Expand Down
34 changes: 22 additions & 12 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37867,6 +37867,7 @@ const errorOnNoSuccessfulWorkflow = process.argv[4];
const lastSuccessfulEvent = process.argv[5];
const workingDirectory = process.argv[6];
const workflowId = process.argv[7];
const fallbackSHA = process.argv[8];
const defaultWorkingDirectory = ".";
const ProxifiedClient = action_1.Octokit.plugin(proxyPlugin);
let BASE_SHA;
Expand Down Expand Up @@ -37913,17 +37914,23 @@ let BASE_SHA;
else {
process.stdout.write("\n");
process.stdout.write(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}', or the latest successful workflow was connected to a commit which no longer exists on that branch (e.g. if that branch was rebased)\n`);
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
process.stdout.write("\n");
process.stdout.write(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);
process.stdout.write("\n");
const commitCountOutput = (0, child_process_1.spawnSync)("git", ["rev-list", "--count", `origin/${mainBranchName}`], { encoding: "utf-8" }).stdout;
const commitCount = parseInt(stripNewLineEndings(commitCountOutput), 10);
const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? "~1" : ""}`;
const baseRes = (0, child_process_1.spawnSync)("git", ["rev-parse", LAST_COMMIT_CMD], {
encoding: "utf-8",
});
BASE_SHA = baseRes.stdout;
if (fallbackSHA) {
BASE_SHA = fallbackSHA;
process.stdout.write(`Using provided fallback SHA: ${fallbackSHA}\n`);
}
else {
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
process.stdout.write("\n");
process.stdout.write(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);
process.stdout.write("\n");
const commitCountOutput = (0, child_process_1.spawnSync)("git", ["rev-list", "--count", `origin/${mainBranchName}`], { encoding: "utf-8" }).stdout;
const commitCount = parseInt(stripNewLineEndings(commitCountOutput), 10);
const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? "~1" : ""}`;
const baseRes = (0, child_process_1.spawnSync)("git", ["rev-parse", LAST_COMMIT_CMD], {
encoding: "utf-8",
});
BASE_SHA = baseRes.stdout;
}
mandarini marked this conversation as resolved.
Show resolved Hide resolved
core.setOutput("noPreviousBuild", "true");
}
}
Expand Down Expand Up @@ -37977,7 +37984,10 @@ function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, lastSucc
owner,
repo,
// on some workflow runs we do not have branch property
branch: lastSuccessfulEvent === "push" || lastSuccessfulEvent === "workflow_dispatch" ? branch : undefined,
branch: lastSuccessfulEvent === "push" ||
lastSuccessfulEvent === "workflow_dispatch"
? branch
: undefined,
workflow_id,
event: lastSuccessfulEvent,
status: "success",
Expand Down
88 changes: 49 additions & 39 deletions find-successful-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const errorOnNoSuccessfulWorkflow = process.argv[4];
const lastSuccessfulEvent = process.argv[5];
const workingDirectory = process.argv[6];
const workflowId = process.argv[7];
const fallbackSHA = process.argv[8];
const defaultWorkingDirectory = ".";

const ProxifiedClient = Octokit.plugin(proxyPlugin);
Expand All @@ -29,7 +30,7 @@ let BASE_SHA: string;
} else {
process.stdout.write("\n");
process.stdout.write(
`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`
`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`,
);
}
}
Expand All @@ -49,7 +50,7 @@ let BASE_SHA: string;
const baseResult = spawnSync(
"git",
["merge-base", `origin/${mainBranchName}`, mergeBaseRef],
{ encoding: "utf-8" }
{ encoding: "utf-8" },
);
BASE_SHA = baseResult.stdout;
} catch (e) {
Expand All @@ -64,7 +65,7 @@ let BASE_SHA: string;
owner,
repo,
mainBranchName,
lastSuccessfulEvent
lastSuccessfulEvent,
);
} catch (e) {
core.setFailed(e.message);
Expand All @@ -76,42 +77,47 @@ let BASE_SHA: string;
reportFailure(mainBranchName);
return;
} else {
process.stdout.write( "\n");
process.stdout.write(
`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}', or the latest successful workflow was connected to a commit which no longer exists on that branch (e.g. if that branch was rebased)\n`
);
process.stdout.write(
`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`
);
process.stdout.write("\n");
process.stdout.write(
`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`
`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}', or the latest successful workflow was connected to a commit which no longer exists on that branch (e.g. if that branch was rebased)\n`,
);
process.stdout.write("\n");
if (fallbackSHA) {
BASE_SHA = fallbackSHA;
process.stdout.write(`Using provided fallback SHA: ${fallbackSHA}\n`);
} else {
process.stdout.write(
`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`,
);
process.stdout.write("\n");
process.stdout.write(
`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`,
);
process.stdout.write("\n");

const commitCountOutput = spawnSync(
"git",
["rev-list", "--count", `origin/${mainBranchName}`],
{ encoding: "utf-8" }
).stdout;
const commitCount = parseInt(
stripNewLineEndings(commitCountOutput),
10
);
const commitCountOutput = spawnSync(
"git",
["rev-list", "--count", `origin/${mainBranchName}`],
{ encoding: "utf-8" },
).stdout;
const commitCount = parseInt(
stripNewLineEndings(commitCountOutput),
10,
);

const LAST_COMMIT_CMD = `origin/${mainBranchName}${
commitCount > 1 ? "~1" : ""
}`;
const baseRes = spawnSync("git", ["rev-parse", LAST_COMMIT_CMD], {
encoding: "utf-8",
});
BASE_SHA = baseRes.stdout;
const LAST_COMMIT_CMD = `origin/${mainBranchName}${
commitCount > 1 ? "~1" : ""
}`;
const baseRes = spawnSync("git", ["rev-parse", LAST_COMMIT_CMD], {
encoding: "utf-8",
});
BASE_SHA = baseRes.stdout;
}
core.setOutput("noPreviousBuild", "true");
}
} else {
process.stdout.write("\n");
process.stdout.write(
`Found the last successful workflow run on 'origin/${mainBranchName}'\n`
`Found the last successful workflow run on 'origin/${mainBranchName}'\n`,
);
process.stdout.write(`Commit: ${BASE_SHA}\n`);
}
Expand Down Expand Up @@ -148,7 +154,7 @@ async function findSuccessfulCommit(
owner: string,
repo: string,
branch: string,
lastSuccessfulEvent: string
lastSuccessfulEvent: string,
): Promise<string | undefined> {
const octokit = new ProxifiedClient();
if (!workflow_id) {
Expand All @@ -162,7 +168,7 @@ async function findSuccessfulCommit(
.then(({ data: { workflow_id } }) => workflow_id);
process.stdout.write("\n");
process.stdout.write(
`Workflow Id not provided. Using workflow '${workflow_id}'\n`
`Workflow Id not provided. Using workflow '${workflow_id}'\n`,
);
}
// fetch all workflow runs on a given repo/branch/workflow with push and success
Expand All @@ -173,14 +179,18 @@ async function findSuccessfulCommit(
owner,
repo,
// on some workflow runs we do not have branch property
branch: lastSuccessfulEvent === "push" || lastSuccessfulEvent === "workflow_dispatch" ? branch : undefined,
branch:
lastSuccessfulEvent === "push" ||
lastSuccessfulEvent === "workflow_dispatch"
? branch
: undefined,
workflow_id,
event: lastSuccessfulEvent,
status: "success",
}
},
)
.then(({ data: { workflow_runs } }) =>
workflow_runs.map((run: { head_sha: any }) => run.head_sha)
workflow_runs.map((run: { head_sha: any }) => run.head_sha),
);

return await findExistingCommit(octokit, branch, shas);
Expand All @@ -198,7 +208,7 @@ async function findMergeBaseRef(): Promise<string> {
function findMergeQueuePr(): string {
const { head_ref, base_sha } = github.context.payload.merge_group;
const result = new RegExp(
`^refs/heads/gh-readonly-queue/${mainBranchName}/pr-(\\d+)-${base_sha}$`
`^refs/heads/gh-readonly-queue/${mainBranchName}/pr-(\\d+)-${base_sha}$`,
).exec(head_ref);
return result ? result.at(1) : undefined;
}
Expand All @@ -213,7 +223,7 @@ async function findMergeQueueBranch(): Promise<string> {
const octokit = new ProxifiedClient();
const result = await octokit.request(
`GET /repos/${owner}/${repo}/pulls/${pull_number}`,
{ owner, repo, pull_number: +pull_number }
{ owner, repo, pull_number: +pull_number },
);
return result.data.head.ref;
}
Expand All @@ -224,7 +234,7 @@ async function findMergeQueueBranch(): Promise<string> {
async function findExistingCommit(
octokit: Octokit,
branchName: string,
shas: string[]
shas: string[],
): Promise<string | undefined> {
for (const commitSha of shas) {
if (await commitExists(octokit, branchName, commitSha)) {
Expand All @@ -240,7 +250,7 @@ async function findExistingCommit(
async function commitExists(
octokit: Octokit,
branchName: string,
commitSha: string
commitSha: string,
): Promise<boolean> {
try {
spawnSync("git", ["cat-file", "-e", commitSha], {
Expand All @@ -263,7 +273,7 @@ async function commitExists(
});

return commits.data.some(
(commit: { sha: string }) => commit.sha === commitSha
(commit: { sha: string }) => commit.sha === commitSha,
);
} catch {
return false;
Expand Down
Loading