Skip to content

Add redirect support for updates with --no-redirect and safe-update approval checks#26903

Merged
pelikhan merged 10 commits intomainfrom
copilot/add-redirect-support-in-front-matter
Apr 17, 2026
Merged

Add redirect support for updates with --no-redirect and safe-update approval checks#26903
pelikhan merged 10 commits intomainfrom
copilot/add-redirect-support-in-front-matter

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

Summary

  • add redirect frontmatter support to schema and typed frontmatter structures
  • make gh aw update follow redirect chains, rewrite source to resolved location, warn on redirect hops, and stop on redirect loops
  • add gh aw update --no-redirect to refuse redirected updates (fails when redirect is present instead of following it)
  • make compile emit an informative message when a redirect is configured
  • extend safe-update approval/security checks to flag redirect additions/removals (including redirect target changes) and include redirect changes in the security review warning message
  • persist redirect in gh-aw-manifest so redirect changes are compared across compilations
  • add focused tests for redirect parsing, redirect chain/loop handling, compile messaging, --no-redirect refusal behavior, redirect-related integration coverage, and redirect safe-update enforcement

Validation

  • go test -run "TestNormalizeRedirectToSourceSpec|TestResolveRedirectedUpdateLocation|TestMergeWorkflowContent_.*|TestRunUpdateWorkflows_NoSourceWorkflows|TestRunUpdateWorkflows_SpecificWorkflowNotFound" ./pkg/cli
  • go test -run "TestResolveRedirectedUpdateLocation/refuses_redirect_when_no-redirect_is_enabled" ./pkg/cli
  • go test -tags=integration -run "TestUpdateCommand_NoRedirectFlag|TestSafeUpdateFirstCompileCreatesBaselineForRedirect" ./pkg/cli
  • go test -run "TestEnforceSafeUpdate|TestBuildSafeUpdateError|TestNewGHAWManifest|TestGHAWManifestToJSON|TestExtractGHAWManifestFromLockFile|TestRedirectFieldExtraction|TestCompileWorkflow_PrintsRedirectInfoMessage|TestParseFrontmatterConfig/parses_complete_workflow_config" ./pkg/workflow
  • make agent-finish (fails due pre-existing unrelated testifylint issues in pkg/constants/spec_test.go)

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot add arg to refuse redirects, --no-redirect

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilo add integration tests

Copilot AI and others added 2 commits April 17, 2026 15:48
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot add arg to refuse redirects, --no-redirect

Implemented with --no-redirect on gh aw update and wired through update resolution. When enabled, update now fails if a workflow declares redirect instead of following it. Addressed in commit 010a890.

Copilot AI changed the title Add frontmatter redirect support for workflow updates Add frontmatter redirect support for workflow updates and --no-redirect opt-out Apr 17, 2026
@pelikhan pelikhan marked this pull request as ready for review April 17, 2026 16:14
Copilot AI review requested due to automatic review settings April 17, 2026 16:14
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot adding or removing a redirect should be flagged by the "approval" checker and added to the security review message.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a redirect frontmatter field to support moved workflow locations, and teaches gh aw update to follow (or refuse) redirect chains while updating workflow source to the resolved location.

Changes:

  • Extend workflow frontmatter types + schema to include redirect, and serialize it back to maps.
  • Emit an informational compiler message when a workflow is configured as a redirect stub.
  • Update gh aw update to resolve redirect chains (with loop/depth protection) and add --no-redirect to fail instead of following redirects, plus related tests.
Show a summary per file
File Description
pkg/workflow/workflow_builder.go Plumbs extracted redirect into initial WorkflowData.
pkg/workflow/redirect_field_test.go Adds tests for redirect extraction and compile messaging.
pkg/workflow/frontmatter_types_test.go Extends typed frontmatter parsing test to include redirect.
pkg/workflow/frontmatter_types.go Adds Redirect to FrontmatterConfig.
pkg/workflow/frontmatter_serialization.go Includes redirect in FrontmatterConfig.ToMap().
pkg/workflow/frontmatter_extraction_metadata.go Implements extractRedirect from raw frontmatter.
pkg/workflow/compiler_types.go Adds Redirect to WorkflowData.
pkg/workflow/compiler.go Prints an info message when Redirect is present.
pkg/parser/schemas/main_workflow_schema.json Adds redirect to the JSON schema.
pkg/cli/update_workflows.go Routes workflow updates through redirect-resolution and adds noRedirect plumbing.
pkg/cli/update_redirects_test.go Adds unit tests for redirect normalization, chain following, loops, and --no-redirect.
pkg/cli/update_redirects.go Implements redirect-chain resolution, normalization, and extraction from content.
pkg/cli/update_merge.go Allows merge helper to accept either a ref or a full new source spec.
pkg/cli/update_command_test.go Updates RunUpdateWorkflows calls for the new parameter.
pkg/cli/update_command.go Adds the --no-redirect flag and plumbs it into update execution.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 15/15 changed files
  • Comments generated: 2

Comment on lines +404 to 409
if !force && currentRef == latestRef && len(resolvedLocation.redirectHistory) == 0 {
updateLog.Printf("Workflow already at latest ref: %s, checking for local modifications", currentRef)

// Download the source content to check if local file has been modified
sourceContent, err := downloadWorkflowContent(ctx, sourceSpec.Repo, sourceSpec.Path, currentRef, verbose)
sourceContent, err := downloadWorkflowContentFn(ctx, sourceSpec.Repo, sourceSpec.Path, currentRef, verbose)
if err != nil {
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

In the up-to-date fast path, this downloads the source content again even though resolveRedirectedUpdateLocation already downloaded resolvedLocation.content at latestRef. When currentRef == latestRef and there were no redirects, you can reuse resolvedLocation.content for the local-modification comparison to avoid an extra network/API call per workflow.

See below for a potential fix:

		// Reuse the resolved source content for comparison since it was already
		// downloaded at latestRef and this fast path only applies when the current
		// ref matches latestRef and no redirects occurred.
		sourceContent := newContent

Copilot uses AI. Check for mistakes.
}

if noRedirect {
return nil, fmt.Errorf("redirect is disabled by --no-redirect for %s: %s declares redirect to %s (remove redirect frontmatter or run update without --no-redirect)", workflowName, sourceSpecWithRef(current, latestRef), redirect)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The --no-redirect error message suggests the user can "remove redirect frontmatter", but the redirect is typically in the upstream (source) workflow file and may not be editable by the user running gh aw update. Consider changing the guidance to something actionable locally (e.g., update the local source field to the redirected location, or rerun without --no-redirect).

Suggested change
return nil, fmt.Errorf("redirect is disabled by --no-redirect for %s: %s declares redirect to %s (remove redirect frontmatter or run update without --no-redirect)", workflowName, sourceSpecWithRef(current, latestRef), redirect)
return nil, fmt.Errorf("redirect is disabled by --no-redirect for %s: %s declares redirect to %s (update your local source to %s or run update without --no-redirect)", workflowName, sourceSpecWithRef(current, latestRef), redirect, redirect)

Copilot uses AI. Check for mistakes.
Generated by Design Decision Gate workflow to capture the architectural
decision to introduce a `redirect` frontmatter field for workflow updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: acda88b

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (451 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/26903-frontmatter-redirect-support-for-workflow-updates.md

What to do next

  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-26903: Frontmatter Redirect Support for Workflow Updates

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.


📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 26903-frontmatter-redirect-support-for-workflow-updates.md for PR #26903).

🔒 This PR cannot merge until an ADR is linked in the PR body.

References: §24575079707

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 167.5K ·

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilo add integration tests

Added integration coverage in pkg/cli for this work: TestUpdateCommand_NoRedirectFlag and TestSafeUpdateFirstCompileCreatesBaselineForRedirect. Addressed in commit 5f078cf.

@copilot adding or removing a redirect should be flagged by the "approval" checker and added to the security review message.

Implemented: safe-update approval checks now flag redirect additions/removals (including redirect target changes), and the security review guidance message now includes redirect changes. Addressed in commits 5f078cf and 5ed3357.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /tmp/go-build560GOSUMDB -trimpath 64/bin/go -p main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/010a890-dirty
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/010a890-dirty --jq [.object.sha, .object.type] | @tsv /tmp/go-build560pkg/workflow/validation_helpers.go -trimpath 64/bin/go -p main -lang=go1.25 go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add frontmatter redirect support for workflow updates and --no-redirect opt-out Add redirect support for updates with --no-redirect and safe-update approval checks Apr 17, 2026
@pelikhan pelikhan merged commit 7890177 into main Apr 17, 2026
51 of 52 checks passed
@pelikhan pelikhan deleted the copilot/add-redirect-support-in-front-matter branch April 17, 2026 16:41
Copilot stopped work on behalf of pelikhan due to an error April 17, 2026 16:41
github-actions bot added a commit that referenced this pull request Apr 18, 2026
…ix codemods

- Add redirect: frontmatter field reference (gh aw update follows redirect chains;
  --no-redirect flag refuses redirected updates)
- Document allowed-base-branches for create-pull-request safe output (enables
  per-run base branch override by the agent within policy-gated glob patterns)
- Add steps-run-secrets-to-env and engine-env-secrets-to-engine-config codemods
  to gh aw fix reference (strict-mode secret leak remediation)

Refs: #26903, #26916, #26919

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants