Skip to content

Commit ac329c1

Browse files
authored
feat: add workflow_call support to agentic maintenance with output variables (#26209)
1 parent 8e0b33c commit ac329c1

3 files changed

Lines changed: 154 additions & 42 deletions

File tree

.github/workflows/agentics-maintenance.yml

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,31 @@ on:
5757
required: false
5858
type: string
5959
default: ''
60+
workflow_call:
61+
inputs:
62+
operation:
63+
description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, clean_cache_memories, validate)'
64+
required: false
65+
type: string
66+
default: ''
67+
run_url:
68+
description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
69+
required: false
70+
type: string
71+
default: ''
72+
outputs:
73+
operation_completed:
74+
description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)'
75+
value: ${{ jobs.run_operation.outputs.operation || inputs.operation }}
76+
applied_run_url:
77+
description: 'The run URL that safe outputs were applied from'
78+
value: ${{ jobs.apply_safe_outputs.outputs.run_url }}
6079

6180
permissions: {}
6281

6382
jobs:
6483
close-expired-entities:
65-
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' || github.event.inputs.operation == '') }}
84+
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
6685
runs-on: ubuntu-slim
6786
permissions:
6887
discussions: write
@@ -109,7 +128,7 @@ jobs:
109128
await main();
110129
111130
cleanup-cache-memory:
112-
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' || github.event.inputs.operation == '' || github.event.inputs.operation == 'clean_cache_memories') }}
131+
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }}
113132
runs-on: ubuntu-slim
114133
permissions:
115134
actions: write
@@ -136,12 +155,14 @@ jobs:
136155
await main();
137156
138157
run_operation:
139-
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation != '' && github.event.inputs.operation != 'safe_outputs' && github.event.inputs.operation != 'create_labels' && github.event.inputs.operation != 'clean_cache_memories' && github.event.inputs.operation != 'validate' && (!(github.event.repository.fork)) }}
158+
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'validate' && (!(github.event.repository.fork)) }}
140159
runs-on: ubuntu-slim
141160
permissions:
142161
actions: write
143162
contents: write
144163
pull-requests: write
164+
outputs:
165+
operation: ${{ steps.record.outputs.operation }}
145166
steps:
146167
- name: Checkout repository
147168
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -176,7 +197,7 @@ jobs:
176197
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
177198
env:
178199
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179-
GH_AW_OPERATION: ${{ github.event.inputs.operation }}
200+
GH_AW_OPERATION: ${{ inputs.operation }}
180201
GH_AW_CMD_PREFIX: ./gh-aw
181202
with:
182203
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -186,15 +207,21 @@ jobs:
186207
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs');
187208
await main();
188209
210+
- name: Record outputs
211+
id: record
212+
run: echo "operation=${{ inputs.operation }}" >> "$GITHUB_OUTPUT"
213+
189214
apply_safe_outputs:
190-
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }}
215+
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }}
191216
runs-on: ubuntu-slim
192217
permissions:
193218
actions: read
194219
contents: write
195220
discussions: write
196221
issues: write
197222
pull-requests: write
223+
outputs:
224+
run_url: ${{ steps.record.outputs.run_url }}
198225
steps:
199226
- name: Checkout actions folder
200227
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -222,7 +249,7 @@ jobs:
222249
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
223250
env:
224251
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
225-
GH_AW_RUN_URL: ${{ github.event.inputs.run_url }}
252+
GH_AW_RUN_URL: ${{ inputs.run_url }}
226253
with:
227254
github-token: ${{ secrets.GITHUB_TOKEN }}
228255
script: |
@@ -231,8 +258,12 @@ jobs:
231258
const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs');
232259
await main();
233260
261+
- name: Record outputs
262+
id: record
263+
run: echo "run_url=${{ inputs.run_url }}" >> "$GITHUB_OUTPUT"
264+
234265
create_labels:
235-
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }}
266+
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }}
236267
runs-on: ubuntu-slim
237268
permissions:
238269
contents: read
@@ -280,7 +311,7 @@ jobs:
280311
await main();
281312
282313
validate_workflows:
283-
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation == 'validate' && (!(github.event.repository.fork)) }}
314+
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'validate' && (!(github.event.repository.fork)) }}
284315
runs-on: ubuntu-latest
285316
permissions:
286317
contents: read
@@ -328,7 +359,7 @@ jobs:
328359
await main();
329360
330361
compile-workflows:
331-
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' || github.event.inputs.operation == '') }}
362+
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
332363
runs-on: ubuntu-slim
333364
permissions:
334365
contents: read
@@ -368,7 +399,7 @@ jobs:
368399
await main();
369400
370401
secret-validation:
371-
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' || github.event.inputs.operation == '') }}
402+
if: ${{ (!(github.event.repository.fork)) && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
372403
runs-on: ubuntu-slim
373404
permissions:
374405
contents: read

pkg/workflow/maintenance_workflow.go

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,25 @@ on:
269269
required: false
270270
type: string
271271
default: ''
272+
workflow_call:
273+
inputs:
274+
operation:
275+
description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, clean_cache_memories, validate)'
276+
required: false
277+
type: string
278+
default: ''
279+
run_url:
280+
description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
281+
required: false
282+
type: string
283+
default: ''
284+
outputs:
285+
operation_completed:
286+
description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)'
287+
value: ${{ jobs.run_operation.outputs.operation || inputs.operation }}
288+
applied_run_url:
289+
description: 'The run URL that safe outputs were applied from'
290+
value: ${{ jobs.apply_safe_outputs.outputs.run_url }}
272291
273292
permissions: {}
274293
@@ -392,6 +411,8 @@ jobs:
392411
actions: write
393412
contents: write
394413
pull-requests: write
414+
outputs:
415+
operation: ${{ steps.record.outputs.operation }}
395416
steps:
396417
- name: Checkout repository
397418
uses: ` + GetActionPin("actions/checkout") + `
@@ -420,7 +441,7 @@ jobs:
420441
uses: ` + GetActionPin("actions/github-script") + `
421442
env:
422443
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
423-
GH_AW_OPERATION: ${{ github.event.inputs.operation }}
444+
GH_AW_OPERATION: ${{ inputs.operation }}
424445
GH_AW_CMD_PREFIX: ` + getCLICmdPrefix(actionMode) + `
425446
with:
426447
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -429,6 +450,10 @@ jobs:
429450
setupGlobals(core, github, context, exec, io, getOctokit);
430451
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs');
431452
await main();
453+
454+
- name: Record outputs
455+
id: record
456+
run: echo "operation=${{ inputs.operation }}" >> "$GITHUB_OUTPUT"
432457
`)
433458

434459
// Add apply_safe_outputs job for workflow_dispatch with operation == 'safe_outputs'
@@ -442,6 +467,8 @@ jobs:
442467
discussions: write
443468
issues: write
444469
pull-requests: write
470+
outputs:
471+
run_url: ${{ steps.record.outputs.run_url }}
445472
steps:
446473
- name: Checkout actions folder
447474
uses: ` + GetActionPin("actions/checkout") + `
@@ -469,14 +496,18 @@ jobs:
469496
uses: ` + GetActionPin("actions/github-script") + `
470497
env:
471498
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
472-
GH_AW_RUN_URL: ${{ github.event.inputs.run_url }}
499+
GH_AW_RUN_URL: ${{ inputs.run_url }}
473500
with:
474501
github-token: ${{ secrets.GITHUB_TOKEN }}
475502
script: |
476503
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
477504
setupGlobals(core, github, context, exec, io, getOctokit);
478505
const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs');
479506
await main();
507+
508+
- name: Record outputs
509+
id: record
510+
run: echo "run_url=${{ inputs.run_url }}" >> "$GITHUB_OUTPUT"
480511
`)
481512

482513
// Add create_labels job for workflow_dispatch with operation == 'create_labels'
@@ -698,57 +729,67 @@ func buildNotForkCondition() ConditionNode {
698729
}
699730
}
700731

701-
// buildNotDispatchOrEmptyOperation creates a condition that is true when the event
702-
// is not a workflow_dispatch or the operation input is empty.
703-
func buildNotDispatchOrEmptyOperation() ConditionNode {
732+
// buildNotDispatchOrCallOrEmptyOperation creates a condition that is true when the event
733+
// is not a workflow_dispatch or workflow_call, or the operation input is empty.
734+
// Uses the `inputs.operation` context which works for both workflow_dispatch and workflow_call.
735+
func buildNotDispatchOrCallOrEmptyOperation() ConditionNode {
704736
return BuildOr(
705-
BuildNotEquals(
706-
BuildPropertyAccess("github.event_name"),
707-
BuildStringLiteral("workflow_dispatch"),
737+
BuildAnd(
738+
BuildNotEquals(
739+
BuildPropertyAccess("github.event_name"),
740+
BuildStringLiteral("workflow_dispatch"),
741+
),
742+
BuildNotEquals(
743+
BuildPropertyAccess("github.event_name"),
744+
BuildStringLiteral("workflow_call"),
745+
),
708746
),
709747
BuildEquals(
710-
BuildPropertyAccess("github.event.inputs.operation"),
748+
BuildPropertyAccess("inputs.operation"),
711749
BuildStringLiteral(""),
712750
),
713751
)
714752
}
715753

716754
// buildNotForkAndScheduledOrOperation creates a condition for jobs that run on
717755
// schedule (or empty operation) AND when a specific operation is selected.
718-
// Condition: !fork && (not_dispatch || operation == || operation == op)
756+
// Condition: !fork && (not_dispatch_or_call || operation == \'\' || operation == op)
719757
func buildNotForkAndScheduledOrOperation(operation string) ConditionNode {
720758
return BuildAnd(
721759
buildNotForkCondition(),
722760
BuildOr(
723-
buildNotDispatchOrEmptyOperation(),
761+
buildNotDispatchOrCallOrEmptyOperation(),
724762
BuildEquals(
725-
BuildPropertyAccess("github.event.inputs.operation"),
763+
BuildPropertyAccess("inputs.operation"),
726764
BuildStringLiteral(operation),
727765
),
728766
),
729767
)
730768
}
731769

732770
// buildNotForkAndScheduled creates a condition for jobs that should run on any
733-
// non-dispatch event (e.g. schedule, push) or on workflow_dispatch with an empty
734-
// operation, and never on forks.
735-
// Condition: !fork && (event_name != 'workflow_dispatch' || operation == "")
771+
// non-dispatch/call event (e.g. schedule, push) or on workflow_dispatch/workflow_call
772+
// with an empty operation, and never on forks.
773+
// Condition: !fork && ((event_name != \'workflow_dispatch\' && event_name != \'workflow_call\') || operation == \'\')
736774
func buildNotForkAndScheduled() ConditionNode {
737775
return BuildAnd(
738776
buildNotForkCondition(),
739-
buildNotDispatchOrEmptyOperation(),
777+
buildNotDispatchOrCallOrEmptyOperation(),
740778
)
741779
}
742780

743781
// buildDispatchOperationCondition creates a condition for jobs that should run
744-
// only when a specific workflow_dispatch operation is selected and not a fork.
745-
// Condition: dispatch && operation == op && !fork
782+
// only when a specific workflow_dispatch or workflow_call operation is selected and not a fork.
783+
// Condition: (dispatch || call) && operation == op && !fork
746784
func buildDispatchOperationCondition(operation string) ConditionNode {
747785
return BuildAnd(
748786
BuildAnd(
749-
BuildEventTypeEquals("workflow_dispatch"),
787+
BuildOr(
788+
BuildEventTypeEquals("workflow_dispatch"),
789+
BuildEventTypeEquals("workflow_call"),
790+
),
750791
BuildEquals(
751-
BuildPropertyAccess("github.event.inputs.operation"),
792+
BuildPropertyAccess("inputs.operation"),
752793
BuildStringLiteral(operation),
753794
),
754795
),
@@ -757,14 +798,17 @@ func buildDispatchOperationCondition(operation string) ConditionNode {
757798
}
758799

759800
// buildRunOperationCondition creates the condition for the unified run_operation
760-
// job that handles all dispatch operations except the ones with dedicated jobs.
761-
// Condition: dispatch && operation != && operation != each excluded && !fork.
801+
// job that handles all dispatch/call operations except the ones with dedicated jobs.
802+
// Condition: (dispatch || call) && operation != \'\' && operation != each excluded && !fork.
762803
func buildRunOperationCondition(excludedOperations ...string) ConditionNode {
763-
// Start with: event is workflow_dispatch AND operation is not empty
804+
// Start with: event is workflow_dispatch or workflow_call AND operation is not empty
764805
condition := BuildAnd(
765-
BuildEventTypeEquals("workflow_dispatch"),
806+
BuildOr(
807+
BuildEventTypeEquals("workflow_dispatch"),
808+
BuildEventTypeEquals("workflow_call"),
809+
),
766810
BuildNotEquals(
767-
BuildPropertyAccess("github.event.inputs.operation"),
811+
BuildPropertyAccess("inputs.operation"),
768812
BuildStringLiteral(""),
769813
),
770814
)
@@ -774,7 +818,7 @@ func buildRunOperationCondition(excludedOperations ...string) ConditionNode {
774818
condition = BuildAnd(
775819
condition,
776820
BuildNotEquals(
777-
BuildPropertyAccess("github.event.inputs.operation"),
821+
BuildPropertyAccess("inputs.operation"),
778822
BuildStringLiteral(op),
779823
),
780824
)

0 commit comments

Comments
 (0)