Skip to content

Commit c1031b9

Browse files
committed
feat(action): fallback sha option
1 parent 0752207 commit c1031b9

File tree

4 files changed

+80
-51
lines changed

4 files changed

+80
-51
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ jobs:
8888
# Default: false
8989
error-on-no-successful-workflow: ""
9090

91+
# 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.
92+
#
93+
# Default: ""
94+
fallback-sha: ""
95+
9196
# The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc.
9297
#
9398
# Default: push

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ inputs:
1111
error-on-no-successful-workflow:
1212
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."
1313
default: "false"
14+
fallback-sha:
15+
description: "Fallback SHA to use if no successful workflow run is found."
16+
required: false
17+
default: ""
1418
last-successful-event:
1519
description: "The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc"
1620
default: "push"

dist/index.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37867,6 +37867,7 @@ const errorOnNoSuccessfulWorkflow = process.argv[4];
3786737867
const lastSuccessfulEvent = process.argv[5];
3786837868
const workingDirectory = process.argv[6];
3786937869
const workflowId = process.argv[7];
37870+
const fallbackSHA = process.argv[8];
3787037871
const defaultWorkingDirectory = ".";
3787137872
const ProxifiedClient = action_1.Octokit.plugin(proxyPlugin);
3787237873
let BASE_SHA;
@@ -37913,17 +37914,23 @@ let BASE_SHA;
3791337914
else {
3791437915
process.stdout.write("\n");
3791537916
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`);
37916-
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
37917-
process.stdout.write("\n");
37918-
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`);
37919-
process.stdout.write("\n");
37920-
const commitCountOutput = (0, child_process_1.spawnSync)("git", ["rev-list", "--count", `origin/${mainBranchName}`], { encoding: "utf-8" }).stdout;
37921-
const commitCount = parseInt(stripNewLineEndings(commitCountOutput), 10);
37922-
const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? "~1" : ""}`;
37923-
const baseRes = (0, child_process_1.spawnSync)("git", ["rev-parse", LAST_COMMIT_CMD], {
37924-
encoding: "utf-8",
37925-
});
37926-
BASE_SHA = baseRes.stdout;
37917+
if (fallbackSHA) {
37918+
BASE_SHA = fallbackSHA;
37919+
process.stdout.write(`Using provided fallback SHA: ${fallbackSHA}\n`);
37920+
}
37921+
else {
37922+
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
37923+
process.stdout.write("\n");
37924+
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`);
37925+
process.stdout.write("\n");
37926+
const commitCountOutput = (0, child_process_1.spawnSync)("git", ["rev-list", "--count", `origin/${mainBranchName}`], { encoding: "utf-8" }).stdout;
37927+
const commitCount = parseInt(stripNewLineEndings(commitCountOutput), 10);
37928+
const LAST_COMMIT_CMD = `origin/${mainBranchName}${commitCount > 1 ? "~1" : ""}`;
37929+
const baseRes = (0, child_process_1.spawnSync)("git", ["rev-parse", LAST_COMMIT_CMD], {
37930+
encoding: "utf-8",
37931+
});
37932+
BASE_SHA = baseRes.stdout;
37933+
}
3792737934
core.setOutput("noPreviousBuild", "true");
3792837935
}
3792937936
}
@@ -37977,7 +37984,10 @@ function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, lastSucc
3797737984
owner,
3797837985
repo,
3797937986
// on some workflow runs we do not have branch property
37980-
branch: lastSuccessfulEvent === "push" || lastSuccessfulEvent === "workflow_dispatch" ? branch : undefined,
37987+
branch: lastSuccessfulEvent === "push" ||
37988+
lastSuccessfulEvent === "workflow_dispatch"
37989+
? branch
37990+
: undefined,
3798137991
workflow_id,
3798237992
event: lastSuccessfulEvent,
3798337993
status: "success",

find-successful-workflow.ts

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const errorOnNoSuccessfulWorkflow = process.argv[4];
1717
const lastSuccessfulEvent = process.argv[5];
1818
const workingDirectory = process.argv[6];
1919
const workflowId = process.argv[7];
20+
const fallbackSHA = process.argv[8];
2021
const defaultWorkingDirectory = ".";
2122

2223
const ProxifiedClient = Octokit.plugin(proxyPlugin);
@@ -29,7 +30,7 @@ let BASE_SHA: string;
2930
} else {
3031
process.stdout.write("\n");
3132
process.stdout.write(
32-
`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`
33+
`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`,
3334
);
3435
}
3536
}
@@ -49,7 +50,7 @@ let BASE_SHA: string;
4950
const baseResult = spawnSync(
5051
"git",
5152
["merge-base", `origin/${mainBranchName}`, mergeBaseRef],
52-
{ encoding: "utf-8" }
53+
{ encoding: "utf-8" },
5354
);
5455
BASE_SHA = baseResult.stdout;
5556
} catch (e) {
@@ -64,7 +65,7 @@ let BASE_SHA: string;
6465
owner,
6566
repo,
6667
mainBranchName,
67-
lastSuccessfulEvent
68+
lastSuccessfulEvent,
6869
);
6970
} catch (e) {
7071
core.setFailed(e.message);
@@ -76,42 +77,47 @@ let BASE_SHA: string;
7677
reportFailure(mainBranchName);
7778
return;
7879
} else {
79-
process.stdout.write( "\n");
80-
process.stdout.write(
81-
`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`
82-
);
83-
process.stdout.write(
84-
`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`
85-
);
8680
process.stdout.write("\n");
8781
process.stdout.write(
88-
`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`
82+
`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`,
8983
);
90-
process.stdout.write("\n");
84+
if (fallbackSHA) {
85+
BASE_SHA = fallbackSHA;
86+
process.stdout.write(`Using provided fallback SHA: ${fallbackSHA}\n`);
87+
} else {
88+
process.stdout.write(
89+
`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`,
90+
);
91+
process.stdout.write("\n");
92+
process.stdout.write(
93+
`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`,
94+
);
95+
process.stdout.write("\n");
9196

92-
const commitCountOutput = spawnSync(
93-
"git",
94-
["rev-list", "--count", `origin/${mainBranchName}`],
95-
{ encoding: "utf-8" }
96-
).stdout;
97-
const commitCount = parseInt(
98-
stripNewLineEndings(commitCountOutput),
99-
10
100-
);
97+
const commitCountOutput = spawnSync(
98+
"git",
99+
["rev-list", "--count", `origin/${mainBranchName}`],
100+
{ encoding: "utf-8" },
101+
).stdout;
102+
const commitCount = parseInt(
103+
stripNewLineEndings(commitCountOutput),
104+
10,
105+
);
101106

102-
const LAST_COMMIT_CMD = `origin/${mainBranchName}${
103-
commitCount > 1 ? "~1" : ""
104-
}`;
105-
const baseRes = spawnSync("git", ["rev-parse", LAST_COMMIT_CMD], {
106-
encoding: "utf-8",
107-
});
108-
BASE_SHA = baseRes.stdout;
107+
const LAST_COMMIT_CMD = `origin/${mainBranchName}${
108+
commitCount > 1 ? "~1" : ""
109+
}`;
110+
const baseRes = spawnSync("git", ["rev-parse", LAST_COMMIT_CMD], {
111+
encoding: "utf-8",
112+
});
113+
BASE_SHA = baseRes.stdout;
114+
}
109115
core.setOutput("noPreviousBuild", "true");
110116
}
111117
} else {
112118
process.stdout.write("\n");
113119
process.stdout.write(
114-
`Found the last successful workflow run on 'origin/${mainBranchName}'\n`
120+
`Found the last successful workflow run on 'origin/${mainBranchName}'\n`,
115121
);
116122
process.stdout.write(`Commit: ${BASE_SHA}\n`);
117123
}
@@ -148,7 +154,7 @@ async function findSuccessfulCommit(
148154
owner: string,
149155
repo: string,
150156
branch: string,
151-
lastSuccessfulEvent: string
157+
lastSuccessfulEvent: string,
152158
): Promise<string | undefined> {
153159
const octokit = new ProxifiedClient();
154160
if (!workflow_id) {
@@ -162,7 +168,7 @@ async function findSuccessfulCommit(
162168
.then(({ data: { workflow_id } }) => workflow_id);
163169
process.stdout.write("\n");
164170
process.stdout.write(
165-
`Workflow Id not provided. Using workflow '${workflow_id}'\n`
171+
`Workflow Id not provided. Using workflow '${workflow_id}'\n`,
166172
);
167173
}
168174
// fetch all workflow runs on a given repo/branch/workflow with push and success
@@ -173,14 +179,18 @@ async function findSuccessfulCommit(
173179
owner,
174180
repo,
175181
// on some workflow runs we do not have branch property
176-
branch: lastSuccessfulEvent === "push" || lastSuccessfulEvent === "workflow_dispatch" ? branch : undefined,
182+
branch:
183+
lastSuccessfulEvent === "push" ||
184+
lastSuccessfulEvent === "workflow_dispatch"
185+
? branch
186+
: undefined,
177187
workflow_id,
178188
event: lastSuccessfulEvent,
179189
status: "success",
180-
}
190+
},
181191
)
182192
.then(({ data: { workflow_runs } }) =>
183-
workflow_runs.map((run: { head_sha: any }) => run.head_sha)
193+
workflow_runs.map((run: { head_sha: any }) => run.head_sha),
184194
);
185195

186196
return await findExistingCommit(octokit, branch, shas);
@@ -198,7 +208,7 @@ async function findMergeBaseRef(): Promise<string> {
198208
function findMergeQueuePr(): string {
199209
const { head_ref, base_sha } = github.context.payload.merge_group;
200210
const result = new RegExp(
201-
`^refs/heads/gh-readonly-queue/${mainBranchName}/pr-(\\d+)-${base_sha}$`
211+
`^refs/heads/gh-readonly-queue/${mainBranchName}/pr-(\\d+)-${base_sha}$`,
202212
).exec(head_ref);
203213
return result ? result.at(1) : undefined;
204214
}
@@ -213,7 +223,7 @@ async function findMergeQueueBranch(): Promise<string> {
213223
const octokit = new ProxifiedClient();
214224
const result = await octokit.request(
215225
`GET /repos/${owner}/${repo}/pulls/${pull_number}`,
216-
{ owner, repo, pull_number: +pull_number }
226+
{ owner, repo, pull_number: +pull_number },
217227
);
218228
return result.data.head.ref;
219229
}
@@ -224,7 +234,7 @@ async function findMergeQueueBranch(): Promise<string> {
224234
async function findExistingCommit(
225235
octokit: Octokit,
226236
branchName: string,
227-
shas: string[]
237+
shas: string[],
228238
): Promise<string | undefined> {
229239
for (const commitSha of shas) {
230240
if (await commitExists(octokit, branchName, commitSha)) {
@@ -240,7 +250,7 @@ async function findExistingCommit(
240250
async function commitExists(
241251
octokit: Octokit,
242252
branchName: string,
243-
commitSha: string
253+
commitSha: string,
244254
): Promise<boolean> {
245255
try {
246256
spawnSync("git", ["cat-file", "-e", commitSha], {
@@ -263,7 +273,7 @@ async function commitExists(
263273
});
264274

265275
return commits.data.some(
266-
(commit: { sha: string }) => commit.sha === commitSha
276+
(commit: { sha: string }) => commit.sha === commitSha,
267277
);
268278
} catch {
269279
return false;

0 commit comments

Comments
 (0)