Skip to content
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
12 changes: 10 additions & 2 deletions .github/workflows/agentics-maintenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,9 @@ jobs:
- name: Build gh-aw
run: make build

- name: Cache activity report logs
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- name: Restore activity report logs cache
id: activity_report_logs_cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
Expand All @@ -372,6 +373,13 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_activity_report.cjs');
await main();

- name: Save activity report logs cache
if: ${{ always() }}
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }}
Comment on lines +376 to +381
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With if: ${{ always() }}, this save step will run even if the build or cache restore step failed/was skipped. In that scenario the referenced output steps.activity_report_logs_cache.outputs.cache-primary-key will be empty, and actions/cache/save will fail because key is required—potentially replacing the original error. Gate this step on the restore step having run and emitting a non-empty primary key output (or provide a fallback key).

Copilot uses AI. Check for mistakes.

close_agentic_workflows_issues:
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'close_agentic_workflows_issues' && (!(github.event.repository.fork)) }}
runs-on: ubuntu-slim
Expand Down
13 changes: 11 additions & 2 deletions pkg/workflow/maintenance_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,17 @@ func TestGenerateMaintenanceWorkflow_OperationJobConditions(t *testing.T) {
t.Errorf("Job activity_report should set timeout-minutes: 120 in:\n%s", activityReportSection)
}
}
if !strings.Contains(yaml, "Cache activity report logs") {
t.Errorf("Job activity_report should include a cache step in:\n%s", yaml)
if !strings.Contains(yaml, "Restore activity report logs cache") {
t.Errorf("Job activity_report should include a cache restore step in:\n%s", yaml)
}
if !strings.Contains(yaml, "Save activity report logs cache") {
t.Errorf("Job activity_report should include a cache save step in:\n%s", yaml)
}
if !strings.Contains(yaml, "if: ${{ always() }}") {
t.Errorf("Job activity_report should save cache even when earlier steps fail in:\n%s", yaml)
}
if !strings.Contains(yaml, "steps.activity_report_logs_cache.outputs.cache-primary-key") {
t.Errorf("Job activity_report cache save step should use cache primary key output in:\n%s", yaml)
}
if !strings.Contains(yaml, "${{ github.run_id }}") {
t.Errorf("Job activity_report cache key should include run_id for latest-cache resolution in:\n%s", yaml)
Expand Down
12 changes: 10 additions & 2 deletions pkg/workflow/maintenance_workflow_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,9 @@ jobs:
`)

yaml.WriteString(generateInstallCLISteps(actionMode, version, actionTag, resolver))
yaml.WriteString(` - name: Cache activity report logs
uses: ` + getActionPin("actions/cache") + `
yaml.WriteString(` - name: Restore activity report logs cache
id: activity_report_logs_cache
uses: ` + getActionPin("actions/cache/restore") + `
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
Expand All @@ -406,6 +407,13 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_activity_report.cjs');
await main();

- name: Save activity report logs cache
if: ${{ always() }}
uses: ` + getActionPin("actions/cache/save") + `
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }}
Comment on lines +411 to +416
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache save step runs with always(), so it will execute even if earlier steps failed and the restore step was skipped. In that case steps.activity_report_logs_cache.outputs.cache-primary-key will be empty/undefined, and actions/cache/save will fail due to a missing key, potentially masking the original failure. Consider gating the save step on the restore step having run and having a non-empty primary key output (or otherwise ensure a fallback key is provided).

Copilot uses AI. Check for mistakes.
`)

// Add close_agentic_workflows_issues job for workflow_dispatch with operation == 'close_agentic_workflows_issues'
Expand Down
12 changes: 10 additions & 2 deletions pkg/workflow/side_repo_maintenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,9 @@ jobs:
`)

yaml.WriteString(generateInstallCLISteps(actionMode, version, actionTag, resolver))
yaml.WriteString(` - name: Cache activity report logs
uses: ` + getActionPin("actions/cache") + `
yaml.WriteString(` - name: Restore activity report logs cache
id: activity_report_logs_cache
uses: ` + getActionPin("actions/cache/restore") + `
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ runner.os }}-activity-report-logs-` + repoSlug + `-${{ github.ref_name }}-${{ github.run_id }}
Expand All @@ -482,6 +483,13 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_activity_report.cjs');
await main();

- name: Save activity report logs cache
if: ${{ always() }}
uses: ` + getActionPin("actions/cache/save") + `
with:
path: ./.cache/gh-aw/activity-report-logs
key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }}
Comment on lines +487 to +492
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this cache save step uses if: ${{ always() }}, it will run even when earlier steps fail and the restore step was skipped. If activity_report_logs_cache didn’t run, steps.activity_report_logs_cache.outputs.cache-primary-key will be empty and actions/cache/save will error due to a missing key, which can obscure the real failure. Add a condition to only run the save when the restore step produced a primary key (or provide a safe fallback key).

Copilot uses AI. Check for mistakes.
`)

// Add validate_workflows job for workflow_dispatch/workflow_call with operation == 'validate'
Expand Down
10 changes: 8 additions & 2 deletions pkg/workflow/side_repo_maintenance_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@ This workflow operates on a separate repository.
// Must have activity_report job.
assert.Contains(t, contentStr, "activity_report:",
"generated workflow should include activity_report job")
assert.Contains(t, contentStr, "Cache activity report logs",
"generated workflow should include cache step for activity_report logs")
assert.Contains(t, contentStr, "Restore activity report logs cache",
"generated workflow should include cache restore step for activity_report logs")
assert.Contains(t, contentStr, "Save activity report logs cache",
"generated workflow should include cache save step for activity_report logs")
assert.Contains(t, contentStr, "if: ${{ always() }}",
"generated workflow should save activity_report logs cache even if report generation fails")
assert.Contains(t, contentStr, "steps.activity_report_logs_cache.outputs.cache-primary-key",
"generated workflow should save activity_report logs using the cache primary key")
assert.Contains(t, contentStr, "GH_AW_ACTIVITY_REPORT_OUTPUT_DIR: ./.cache/gh-aw/activity-report-logs",
"generated workflow should set GH_AW_ACTIVITY_REPORT_OUTPUT_DIR for activity_report logs")
assert.Contains(t, contentStr, "actions: read\n contents: read\n issues: write",
Expand Down
Loading