Skip to content
Closed
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
3 changes: 1 addition & 2 deletions .github/workflows/agentic-observability-kit.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/agentic-optimization-kit.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/ai-moderator.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/api-consumption-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/audit-workflows.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/cloclo.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/copilot-agent-analysis.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/copilot-opt.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/copilot-pr-merged-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/copilot-pr-prompt-analysis.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/copilot-session-insights.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/daily-firewall-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/daily-issues-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/daily-performance-summary.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/deep-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/developer-docs-consolidator.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/github-mcp-structural-analysis.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/poem-bot.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/python-data-charts.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/repo-audit-analyzer.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/repository-quality-improver.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/schema-consistency-checker.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions .github/workflows/stale-repo-identifier.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 26 additions & 34 deletions pkg/workflow/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ func parseCacheMemoryEntry(cacheMap map[string]any, defaultID string) (CacheMemo
if err := validateNoCacheKeyRunID(keyStr); err != nil {
return entry, err
}
// Store the key as-is — do NOT append run_id.
// Custom keys are stable by design: the user's key is reused verbatim across runs
// so the same primary cache entry can be restored on every run.
// (Default keys generated by generateDefaultCacheKey include run_id for rolling-cache
// behaviour, but user-supplied keys bypass that scheme.)
entry.Key = keyStr
// Automatically append -${{ github.run_id }} if the key doesn't already end with it
runIdSuffix := "-${{ github.run_id }}"
if !strings.HasSuffix(entry.Key, runIdSuffix) {
entry.Key = entry.Key + runIdSuffix
}
}
}

Expand Down Expand Up @@ -460,18 +460,17 @@ func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData) {
}

// Use integrity-aware cache key (includes integrity level + policy hash prefix).
// Custom keys are stable (no run_id); default keys are rolling (include run_id).
cacheKey := computeIntegrityCacheKey(cache, githubConfig)

// Ensure run_id suffix is present (computeIntegrityCacheKey guarantees this,
// but we check again for clarity and safety).
runIdSuffix := "-${{ github.run_id }}"
if !strings.HasSuffix(cacheKey, runIdSuffix) {
cacheKey = cacheKey + runIdSuffix
}

// Generate restore keys based on scope
// - "workflow" (default): Single restore key with workflow ID (secure)
// - "repo": Two restore keys - with and without workflow ID (allows cross-workflow sharing)
// Generate restore keys based on key type and scope.
// - Stable custom keys: no restore key needed — the primary key IS stable.
// - Rolling default keys (include run_id): restore key strips run_id so the
// most-recent previous entry can be found after a run_id change.
//
// Scope:
// - "workflow" (default): restore key is scoped to the workflow ID (secure)
// - "repo": additional restore key without workflow ID (cross-workflow sharing)
var restoreKeys []string

// Determine scope (default to "workflow" for safety)
Expand All @@ -480,30 +479,23 @@ func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData) {
scope = "workflow"
}

// First restore key: remove the run_id suffix as a single unit (don't split the key)
// The cacheKey always ends with "-${{ github.run_id }}" (ensured by code above)
runIdSuffix := "-${{ github.run_id }}"

// Only rolling keys (default, with run_id) need restore keys.
// Stable custom keys match their own primary key on every run, so no fallback is needed.
if strings.HasSuffix(cacheKey, runIdSuffix) {
// Remove the run_id suffix to create the restore key
// Remove the run_id suffix to create the workflow-scoped restore key
restoreKey := strings.TrimSuffix(cacheKey, "${{ github.run_id }}") // Keep the trailing "-"
restoreKeys = append(restoreKeys, restoreKey)
} else {
// Fallback: split on last dash if run_id suffix not found
// This handles edge cases where the key format might be different
keyParts := strings.Split(cacheKey, "-")
if len(keyParts) >= 2 {
workflowLevelKey := strings.Join(keyParts[:len(keyParts)-1], "-") + "-"
restoreKeys = append(restoreKeys, workflowLevelKey)
}
}

// For repo scope, add an additional restore key without the workflow ID
// This allows cache sharing across all workflows in the repository
if scope == "repo" {
// Remove both workflow and run_id to create a repo-wide restore key
// For repo scope, add an additional restore key without the workflow ID
// This allows cache sharing across all workflows in the repository.
// For example: "memory-none-nopolicy-chroma-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }}" -> "memory-none-nopolicy-chroma-"
repoKey := strings.TrimSuffix(cacheKey, "${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }}")
if repoKey != cacheKey && repoKey != "" {
restoreKeys = append(restoreKeys, repoKey)
if scope == "repo" {
repoKey := strings.TrimSuffix(cacheKey, "${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }}")
if repoKey != cacheKey && repoKey != "" {
restoreKeys = append(restoreKeys, repoKey)
}
}
}

Expand Down
Loading