-
Notifications
You must be signed in to change notification settings - Fork 4
fix: add success-conclusions as an optional input to control what syn… #307
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
Changes from all commits
d966df4
4472e91
e8729d8
26d3fab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,18 @@ import * as PackageJSON from '../package.json' | |||||||||||||||
|
|
||||||||||||||||
| const API_VERSION = '2026-03-10' // Latest API version as of March 2026, update as needed | ||||||||||||||||
|
|
||||||||||||||||
| const KNOWN_CONCLUSIONS = new Set([ | ||||||||||||||||
| 'success', | ||||||||||||||||
| 'failure', | ||||||||||||||||
| 'neutral', | ||||||||||||||||
| 'cancelled', | ||||||||||||||||
| 'skipped', | ||||||||||||||||
| 'timed_out', | ||||||||||||||||
| 'action_required', | ||||||||||||||||
| 'stale', | ||||||||||||||||
| 'startup_failure', | ||||||||||||||||
| ]) | ||||||||||||||||
|
|
||||||||||||||||
| type Workflow = { | ||||||||||||||||
| id: number | ||||||||||||||||
| name: string | ||||||||||||||||
|
|
@@ -30,6 +42,33 @@ async function run(): Promise<void> { | |||||||||||||||
|
|
||||||||||||||||
| // Required inputs | ||||||||||||||||
| const workflowRef = core.getInput('workflow') | ||||||||||||||||
| const waitForCompletion = core.getInput('wait-for-completion') === 'true' | ||||||||||||||||
| const syncStatus = core.getInput('sync-status') === 'true' | ||||||||||||||||
|
|
||||||||||||||||
| // Read and validate success-conclusions before dispatching the workflow — | ||||||||||||||||
| // a typo changes the verdict, so failing here beats triggering a run we | ||||||||||||||||
| // then refuse to judge. Only parsed when sync-status is true; when | ||||||||||||||||
| // sync-status is false the input is documented as ignored, so we skip it. | ||||||||||||||||
| // If not set, successConclusions is null and legacy conclusion handling | ||||||||||||||||
| // is preserved (failure/cancelled fail, other completed conclusions pass). | ||||||||||||||||
| const configuredSuccessConclusions = core.getInput('success-conclusions') | ||||||||||||||||
| const successConclusions = | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The guard
Suggested change
|
||||||||||||||||
| syncStatus && configuredSuccessConclusions | ||||||||||||||||
| ? new Set( | ||||||||||||||||
| configuredSuccessConclusions | ||||||||||||||||
| .split(',') | ||||||||||||||||
| .map((c) => c.trim().toLowerCase()) | ||||||||||||||||
| .filter(Boolean), | ||||||||||||||||
| ) | ||||||||||||||||
| : null | ||||||||||||||||
| if (successConclusions) { | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The validation guard checks
Suggested change
|
||||||||||||||||
| const unknownConclusions = [...successConclusions].filter((c) => !KNOWN_CONCLUSIONS.has(c)) | ||||||||||||||||
| if (unknownConclusions.length > 0) { | ||||||||||||||||
| throw new Error( | ||||||||||||||||
| `Invalid 'success-conclusions' value(s): ${unknownConclusions.join(', ')}. Valid values: ${[...KNOWN_CONCLUSIONS].join(', ')}`, | ||||||||||||||||
| ) | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Optional inputs, with defaults | ||||||||||||||||
| const token = core.getInput('token') | ||||||||||||||||
|
|
@@ -95,8 +134,6 @@ async function run(): Promise<void> { | |||||||||||||||
| core.info(`🌐 Run URL: ${dispatchResp.data.html_url}`) | ||||||||||||||||
|
|
||||||||||||||||
| // Handle wait for completion | ||||||||||||||||
| const waitForCompletion = core.getInput('wait-for-completion') === 'true' | ||||||||||||||||
| const syncStatus = core.getInput('sync-status') === 'true' | ||||||||||||||||
| const timeoutSeconds = parseInt(core.getInput('wait-timeout-seconds') || '900', 10) // Default to 15 minutes | ||||||||||||||||
| const waitIntervalSeconds = parseInt(core.getInput('wait-interval-seconds') || '5', 10) // Default to 5 seconds | ||||||||||||||||
| let runStatus = 'in_progress' | ||||||||||||||||
|
|
@@ -154,15 +191,33 @@ async function run(): Promise<void> { | |||||||||||||||
| headers: { 'x-github-api-version': API_VERSION }, | ||||||||||||||||
| }, | ||||||||||||||||
| ) | ||||||||||||||||
| const runStatusNow = finalRunData.status | ||||||||||||||||
| const conclusion = finalRunData.conclusion | ||||||||||||||||
|
|
||||||||||||||||
| // Set this action to failed if the triggered workflow run failed or was cancelled | ||||||||||||||||
| if (conclusion === 'failure') { | ||||||||||||||||
| core.setFailed(`Workflow run failed. Check the run details here: ${dispatchResp.data.html_url}`) | ||||||||||||||||
| } else if (conclusion === 'cancelled') { | ||||||||||||||||
| core.setFailed(`Workflow run was cancelled. Check the run details here: ${dispatchResp.data.html_url}`) | ||||||||||||||||
| // An incomplete run has no conclusion yet, so passing here would report | ||||||||||||||||
| // success for work still in flight (e.g. after the wait above timed out). | ||||||||||||||||
| if (runStatusNow !== 'completed') { | ||||||||||||||||
| core.setFailed( | ||||||||||||||||
| `Workflow run did not complete (status: ${runStatusNow}). Check the run details here: ${dispatchResp.data.html_url}`, | ||||||||||||||||
| ) | ||||||||||||||||
| } else if (successConclusions) { | ||||||||||||||||
| // New configurable behaviour — only when success-conclusions is explicitly set | ||||||||||||||||
| if (conclusion && successConclusions.has(conclusion)) { | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||
| core.info(`🎉 Workflow conclusion: ${conclusion}`) | ||||||||||||||||
| } else { | ||||||||||||||||
| core.setFailed( | ||||||||||||||||
| `Workflow run concluded '${conclusion}'. Check the run details here: ${dispatchResp.data.html_url}`, | ||||||||||||||||
| ) | ||||||||||||||||
| } | ||||||||||||||||
| } else { | ||||||||||||||||
| core.info(`🎉 Workflow conclusion: ${conclusion}`) | ||||||||||||||||
| // Old behaviour preserved exactly — only failure and cancelled fail | ||||||||||||||||
| if (conclusion === 'failure') { | ||||||||||||||||
| core.setFailed(`Workflow run failed. Check the run details here: ${dispatchResp.data.html_url}`) | ||||||||||||||||
| } else if (conclusion === 'cancelled') { | ||||||||||||||||
| core.setFailed(`Workflow run was cancelled. Check the run details here: ${dispatchResp.data.html_url}`) | ||||||||||||||||
| } else { | ||||||||||||||||
| core.info(`🎉 Workflow conclusion: ${conclusion}`) | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } catch (error) { | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing README documentation — this new input has no entry in
README.md's "Action Inputs" section. Please add a### success-conclusionsblock describing:success,failure,neutral,cancelled,skipped,timed_out,action_required,stale,startup_failure)sync-status: trueandwait-for-completion: truefailure/cancelledfail)Also update the
### sync-statusdescription to cross-reference this input, since the current wording ("fails or is cancelled") is no longer the full picture.