Skip to content

Document cpflow upstream testing#746

Merged
justin808 merged 1 commit into
masterfrom
jg-codex/document-cpflow-upstream-testing
May 23, 2026
Merged

Document cpflow upstream testing#746
justin808 merged 1 commit into
masterfrom
jg-codex/document-cpflow-upstream-testing

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented May 23, 2026

Summary

  • document how downstream apps can test unreleased control-plane-flow PRs by pinning to an upstream commit SHA
  • clarify the split between GitHub reusable workflow refs, control_plane_flow_ref, and CPFLOW_VERSION
  • add bin/pin-cpflow-github-ref and a ref-consistency guard to bin/test-cpflow-github-flow

Verification

  • bin/conductor-exec bin/pin-cpflow-github-ref 3e0e7e1f0a35c15648cc9254b573b058d77ca8c4
  • bin/test-cpflow-github-flow
  • git diff --check

Note

Low Risk
Low risk: changes are documentation plus local helper scripts/validation for generated workflow refs; no production runtime code paths are modified.

Overview
Clarifies how downstream repos should pin and validate cpflow-* GitHub Actions when testing unreleased control-plane-flow changes, including a step-by-step process for using an upstream PR commit SHA and keeping uses: and control_plane_flow_ref aligned.

Adds bin/pin-cpflow-github-ref to bulk-update all generated wrapper refs (rejecting moving branch refs by default) and extends bin/test-cpflow-github-flow to fail if wrappers use inconsistent upstream refs or if secret-inheriting reusable workflow jobs omit control_plane_flow_ref.

Reviewed by Cursor Bugbot for commit 29aec12. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added a tool to pin downstream workflow wrappers to a specific upstream ref.
    • Added a readiness check that validates wrappers keep their upstream refs aligned and detect mismatches/missing refs.
  • Documentation

    • Expanded end-to-end testing guidance for unreleased upstream workflow changes, including a step-by-step unmerged-PR testing and real review-app deploy verification.
    • Added practical checklists and CI/automation recommendations to catch ref mismatches and parsing issues earlier.

Review Change Stack

@github-actions
Copy link
Copy Markdown

🚀 Quick Review App Commands

Welcome! Here are the commands you can use in this PR:

+review-app-deploy

Deploy your PR branch for testing.

+review-app-delete

Remove the review app when done.

+review-app-help

Show detailed instructions, environment setup, and configuration options.

Comment +review-app-help for full setup details.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Walkthrough

Adds a ref-pinning CLI (bin/pin-cpflow-github-ref), strengthens ref-consistency validation (bin/test-cpflow-github-flow), and updates documentation (.github and .controlplane) describing how to test upstream reusable workflow changes by pinning wrapper refs to immutable upstream commit SHAs.

Changes

cpflow Ref Pinning Tooling and Testing Guidance

Layer / File(s) Summary
Pinning script implementation
bin/pin-cpflow-github-ref
New executable that parses options (including --allow-moving-ref), validates the provided ref (SHA or v* tag unless allowed), finds .github/workflows/cpflow-*.yml, and rewrites both uses: and control_plane_flow_ref to the pinned ref; reports updated files.
Ref consistency validation
bin/test-cpflow-github-flow
Adds validation that scans cpflow-*.yml wrappers, extracts @ref from uses: and control_plane_flow_ref, enforces required inputs when secrets are inherited, aggregates discovered refs, and aborts if multiple distinct upstream refs are present or if mismatches are found.
General GitHub Actions testing guidance
.github/testing-github-actions.md
Replaces narrative workarounds with a concise mapping of which workflow code runs per event and a practical checklist for local validation, CI YAML parsing checks, workflow_dispatch --ref testing, and pinned reusable-workflow validation.
cpflow-specific testing and pinning workflow documentation
.controlplane/docs/testing-cpflow-github-actions.md, .controlplane/readme.md
Documents pinning wrappers to upstream PR commit SHAs for testing unmerged upstream changes, clarifies CPFLOW_VERSION behavior, adds local readiness checks requiring aligned uses: and control_plane_flow_ref, and proposes tooling and CI improvements.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as bin/pin-cpflow-github-ref
  participant Repo as cpflow-wrapper-file(s)
  participant Validator as bin/test-cpflow-github-flow
  CLI->>Repo: update `uses: ...@<ref>` and `control_plane_flow_ref: <ref>`
  Repo->>Validator: validator loads `cpflow-*.yml`
  Validator->>Repo: extract `uses:` `@ref` and `with.control_plane_flow_ref`
  Validator->>Validator: compare refs and check secrets input
  Validator-->>CLI: report single ref found or abort on mismatch
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through YAML with a tiny drum,

Pinned each ref until the checks went hum.
Scripts and docs in tidy array,
Review apps dance at end of day,
A rabbit claps — CI sings, hooray!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Document cpflow upstream testing' accurately and concisely summarizes the primary change: adding documentation and helper scripts for testing unreleased cpflow/control-plane-flow upstream PRs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg-codex/document-cpflow-upstream-testing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 23, 2026

Greptile Summary

This PR documents how downstream apps can test unreleased control-plane-flow PRs by pinning workflow wrappers to an upstream commit SHA, and adds tooling to support that workflow. It introduces bin/pin-cpflow-github-ref to rewrite all generated wrapper refs in one step, extends bin/test-cpflow-github-flow with a ref-consistency guard, and rewrites .github/testing-github-actions.md into a concise summary that delegates cpflow detail to the controlplane doc.

  • New script bin/pin-cpflow-github-ref rewrites every cpflow-*.yml wrapper's uses: ref and control_plane_flow_ref to a given tag or commit SHA in a single command.
  • Consistency guard added to bin/test-cpflow-github-flow aborts when uses: and control_plane_flow_ref disagree within a file, but currently does not abort when different files carry different refs.
  • Documentation additions clarify the three-way split between the reusable workflow @-ref, control_plane_flow_ref, and CPFLOW_VERSION.

Confidence Score: 4/5

Safe to merge; the only gap is that the new ref-consistency check does not fail when different workflow files carry different upstream refs.

The new bin/pin-cpflow-github-ref script is well-scoped and safe. The consistency guard in bin/test-cpflow-github-flow correctly catches intra-file ref mismatches, but it only logs — and does not abort on — cross-file divergence. Because the primary stated goal of the guard is to prevent exactly that split-ref situation from silently passing CI, the partial coverage is a real gap in the tooling being introduced.

bin/test-cpflow-github-flow — the new ref-consistency check block (lines 41-65)

Important Files Changed

Filename Overview
bin/pin-cpflow-github-ref New Ruby script that rewrites every cpflow-*.yml wrapper to a given ref; input validation and gsub substitution logic look correct.
bin/test-cpflow-github-flow Adds a ref-consistency check, but only aborts on intra-file mismatches; cross-file ref divergence is logged but not treated as a failure.
.controlplane/docs/testing-cpflow-github-actions.md Adds detailed upstream-PR testing walkthrough and clarifies the relationship between workflow refs, control_plane_flow_ref, and CPFLOW_VERSION.
.controlplane/readme.md Adds a short prose paragraph pointing to bin/pin-cpflow-github-ref for pre-release upstream testing; no issues.
.github/testing-github-actions.md Rewrites verbose workaround guide into a concise, accurate summary; delegates cpflow-specific detail to the controlplane doc.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Developer: upstream PR ready to test] --> B[bin/pin-cpflow-github-ref SHA]
    B --> C[Rewrites uses: @ref in cpflow-*.yml]
    B --> D[Rewrites control_plane_flow_ref in cpflow-*.yml]
    C --> E[bin/test-cpflow-github-flow]
    D --> E
    E --> F{cpflow github-flow-readiness}
    E --> G{Parse YAML}
    E --> H{Check action input descriptions}
    E --> I{Check ref consistency per-file}
    I -->|intra-file mismatch| J[abort]
    I -->|cross-file mismatch| K[prints multiple refs — no abort]
    I -->|all consistent| L[actionlint]
    L --> M[Open downstream PR + comment +review-app-deploy]
    M --> N{Review app deploy succeeds?}
    N -->|yes| O[Upstream PR merges + releases]
    O --> P[Regenerate or repin to release tag]
    N -->|no| Q[Debug upstream PR]
Loading

Reviews (1): Last reviewed commit: "Document cpflow upstream testing" | Re-trigger Greptile

Comment on lines +41 to +65
echo "==> check cpflow reusable workflow refs"
bin/conductor-exec ruby <<'RUBY'
refs = Hash.new { |hash, key| hash[key] = [] }

Dir[".github/workflows/cpflow-*.yml"].sort.each do |path|
text = File.read(path)
uses_refs = text.scan(%r{uses:\s+shakacode/control-plane-flow/\.github/workflows/[^@\s]+@([^\s]+)}).flatten
input_refs = text.scan(/^\s*control_plane_flow_ref:\s*(\S+)/).flatten

(uses_refs + input_refs).each { |ref| refs[ref] << path }

next if uses_refs.empty? && input_refs.empty?

expected = uses_refs.first
mismatches = (uses_refs + input_refs).uniq
abort "#{path}: mismatched cpflow refs: #{mismatches.join(', ')}" if mismatches.length > 1
abort "#{path}: missing control_plane_flow_ref for #{expected}" if input_refs.empty? && path !~ /cpflow-(help-command|review-app-help)\.yml\z/
end

if refs.empty?
puts "no upstream cpflow reusable workflow refs found"
else
puts "cpflow refs: #{refs.keys.sort.join(', ')}"
end
RUBY
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Cross-file ref inconsistency not detected

The guard aborts when uses: and control_plane_flow_ref disagree within a single file, but if file_a.yml pins sha_a and file_b.yml pins sha_b, the loop passes both without aborting — the only evidence is the printed cpflow refs: sha_a, sha_b output. Any CI job that doesn't inspect stdout carefully would pass silently with mismatched refs across the generated wrappers, which is the exact split-ref scenario the guard is meant to prevent.

Comment thread bin/pin-cpflow-github-ref
exit 1
end

unless ref.match?(/\A[0-9A-Za-z._\/-]+\z/)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The validation regex \A[0-9A-Za-z._\/-]+\z allows forward slashes, so branch names like main or feature/my-branch pass silently. The docs explicitly warn against mutable branch refs, but the script doesn't enforce it.

Consider adding a soft warning (or hard failure) when the ref is neither a full 40-char SHA nor a v-prefixed semver tag:

Suggested change
unless ref.match?(/\A[0-9A-Za-z._\/-]+\z/)
unless ref.match?(/\A[0-9A-Za-z._\/-]+\z/)
warn "Ref contains unsupported characters: #{ref.inspect}"
exit 1
end
if ref.include?("/") || (ref !~ /\A[0-9a-f]{40}\z/ && ref !~ /\Av\d/)
warn "Warning: #{ref.inspect} looks like a branch name — use a full commit SHA or release tag instead."
end

Comment thread bin/test-cpflow-github-flow Outdated
expected = uses_refs.first
mismatches = (uses_refs + input_refs).uniq
abort "#{path}: mismatched cpflow refs: #{mismatches.join(', ')}" if mismatches.length > 1
abort "#{path}: missing control_plane_flow_ref for #{expected}" if input_refs.empty? && path !~ /cpflow-(help-command|review-app-help)\.yml\z/
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The exempt workflow name list (cpflow-(help-command|review-app-help)) is hardcoded inline. If a new wrapper legitimately omits control_plane_flow_ref, this regex must be updated and is easy to miss. Consider extracting it to a named constant near the top of the heredoc:

EXEMPT_WORKFLOWS = /cpflow-(help-command|review-app-help)\.yml\z/

# ...later...
abort "#{path}: missing control_plane_flow_ref for #{expected}" if input_refs.empty? && path !~ EXEMPT_WORKFLOWS

Comment thread bin/test-cpflow-github-flow Outdated

next if uses_refs.empty? && input_refs.empty?

expected = uses_refs.first
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Logic gap: if uses_refs is empty but input_refs is non-empty (a control_plane_flow_ref value with no corresponding reusable uses: line), the next guard is skipped, expected is nil, and neither abort fires — a dangling control_plane_flow_ref is silently accepted.

Consider adding an explicit guard after the next line:

next if uses_refs.empty? && input_refs.empty?

abort "#{path}: has control_plane_flow_ref but no reusable uses: line" if uses_refs.empty?

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d767699f9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bin/test-cpflow-github-flow Outdated
Comment on lines +52 to +56
next if uses_refs.empty? && input_refs.empty?

expected = uses_refs.first
mismatches = (uses_refs + input_refs).uniq
abort "#{path}: mismatched cpflow refs: #{mismatches.join(', ')}" if mismatches.length > 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require a matched cpflow uses: ref per wrapper

The new ref-consistency check only validates mismatches after parsing refs, but it never fails when control_plane_flow_ref exists and the cpflow uses: line is missing or unparsable. In that case uses_refs is empty, mismatches has one value, and the script exits successfully, so a broken wrapper can pass local validation and CI. This can happen if the uses: line is reformatted (e.g., quoted/templated) or accidentally changed away from the expected repo path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Cross-file ref consistency check never enforced
    • Added an abort when generated workflow wrappers contain more than one upstream cpflow ref across files.

Create PR

Or push these changes by commenting:

@cursor push 20d24f1de7
Preview (20d24f1de7)
diff --git a/bin/test-cpflow-github-flow b/bin/test-cpflow-github-flow
--- a/bin/test-cpflow-github-flow
+++ b/bin/test-cpflow-github-flow
@@ -59,6 +59,9 @@
 
 if refs.empty?
   puts "no upstream cpflow reusable workflow refs found"
+elsif refs.keys.length > 1
+  details = refs.keys.sort.map { |ref| "#{ref}: #{refs[ref].uniq.sort.join(', ')}" }
+  abort "mismatched cpflow refs across workflows:\n#{details.join("\n")}"
 else
   puts "cpflow refs: #{refs.keys.sort.join(', ')}"
 end

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 7d76769. Configure here.

Comment thread bin/test-cpflow-github-flow
@claude
Copy link
Copy Markdown

claude Bot commented May 23, 2026

placeholder

@claude
Copy link
Copy Markdown

claude Bot commented May 23, 2026

Code Review

Overall: Low-risk, well-scoped PR. The documentation improvements are clear and well-structured, and the new bin/pin-cpflow-github-ref script is straightforward. Three issues worth addressing before merge.

What the PR does

  • Adds a step-by-step guide for testing unmerged upstream control-plane-flow PRs downstream by pinning both the reusable workflow uses: ref and control_plane_flow_ref to an immutable commit SHA.
  • Adds bin/pin-cpflow-github-ref to mass-update generated cpflow-*.yml wrapper refs in one command.
  • Extends bin/test-cpflow-github-flow with a ref-consistency guard that fails if uses: and control_plane_flow_ref drift within any wrapper.
  • Refactors .github/testing-github-actions.md from a verbose workarounds list into a concise summary pointing to the cpflow-specific guide.

Issues (inline comments posted)

  1. bin/pin-cpflow-github-ref line 14 — ref validation too permissive
    The regex allows forward slashes, so a branch name like main or feature/my-branch passes without warning. The docs correctly say to never use a moving branch ref, but the script does not enforce it. A simple heuristic (not a 40-char hex SHA and not a v-prefixed semver) could warn users before they accidentally commit a mutable ref.

  2. bin/test-cpflow-github-flow — hardcoded exempt workflow list
    The cpflow-(help-command|review-app-help) exception is buried inline in the abort condition. Extracting it to a named constant would make the exemption explicit and easier to extend when new exempt wrappers are added.

  3. bin/test-cpflow-github-flow — logic gap with dangling control_plane_flow_ref
    If a file has control_plane_flow_ref but no reusable uses: line, it silently passes the consistency check. An explicit guard immediately after the next line would close this gap.

Minor notes

  • bin/pin-cpflow-github-ref uses regex-based YAML mutation rather than a YAML parser. This is pragmatic for generated files with a stable structure, but a --dry-run flag to preview changes before writing would reduce the risk of unexpected edits.
  • The .github/testing-github-actions.md refactor loses some explanatory detail but the concise version is much easier to scan — a net improvement.
  • No tests for bin/pin-cpflow-github-ref, which is acceptable for a local developer utility.

@justin808 justin808 force-pushed the jg-codex/document-cpflow-upstream-testing branch from 7d76769 to 1bef2ca Compare May 23, 2026 20:30
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1bef2ca1d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bin/test-cpflow-github-flow Outdated

(uses_refs + input_refs).each { |ref| refs[ref] << path }

next if uses_refs.empty? && input_refs.empty?
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require cpflow refs in non-exempt wrappers

The early next lets a cpflow-*.yml file pass with neither a parsed reusable-workflow uses: ref nor a control_plane_flow_ref, so the new guard can silently skip broken wrappers. In practice, if a non-exempt wrapper is edited so both patterns are absent/unmatched (for example by changing the repo path in uses: and dropping the input), this check exits successfully instead of failing, which defeats the intended ref-consistency validation.

Useful? React with 👍 / 👎.

@claude
Copy link
Copy Markdown

claude Bot commented May 23, 2026

Code Review

Overall: Low-risk, well-scoped PR. Documentation quality is noticeably improved, and the new helper scripts add real validation value. A few things worth addressing before merge.


What this PR does

  • Adds step-by-step guidance for testing unreleased upstream control-plane-flow changes downstream without publishing a gem
  • Introduces bin/pin-cpflow-github-ref to atomically update all cpflow-* wrapper refs to a commit SHA or release tag
  • Extends bin/test-cpflow-github-flow with a ref-consistency guard that fails on mismatched or missing control_plane_flow_ref entries
  • Streamlines .github/testing-github-actions.md from 85 to 34 lines by delegating cpflow detail to the dedicated guide

Issues

bin/pin-cpflow-github-ref — fragile relative-path display (line 64)
path.delete_prefix("#{root}/") relies on string prefix matching between a Dir[] result and Pathname#expand_path output. If the two don't share the exact same format (trailing slash, symlink resolution, etc.) the full absolute path silently leaks into the output. Use Pathname#relative_path_from instead:

changed << Pathname.new(path).relative_path_from(root).to_s

bin/test-cpflow-github-flow — hardcoded exemption list will drift (lines 43-46)
WORKFLOWS_WITHOUT_CONTROL_PLANE_FLOW_REF names two specific files. As workflows are added, renamed, or removed, this list will silently become stale — either falsely passing files that should have the ref, or failing on newly exempted ones. Consider detecting the exemption condition from the workflow content itself (e.g., workflows that have no uses: shakacode/control-plane-flow line at all) rather than an explicit allowlist.


Minor observations

  • The next if uses_refs.empty? && input_refs.empty? guard in bin/test-cpflow-github-flow comes after the (uses_refs + input_refs).each accumulation. For the empty-empty case the accumulation is a no-op, so this is not a bug — but moving the next before the accumulation would make the intent clearer.
  • bin/pin-cpflow-github-ref has no --dry-run option. Given that it batch-rewrites files, a dry-run mode would be a low-effort safety net; could make a good follow-up.
  • The RELEASE_TAG regex character class [.-] puts - after ., making it literal by position. This is correct Ruby behaviour but is easy to misread — [\-.] or [-.] would be unambiguous.

Documentation

The refactored .github/testing-github-actions.md is much cleaner. The original had several workaround recipes that no longer apply cleanly to this repo's cpflow-centric workflow; removing them in favour of a pointer to the detailed guide is the right call.

Comment thread bin/pin-cpflow-github-ref Outdated
next if updated == text

File.write(path, updated)
changed << path.delete_prefix("#{root}/")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

String prefix stripping is fragile here — if Dir[] and Pathname#expand_path produce subtly different paths (symlink resolution, trailing slash, etc.) the full absolute path leaks silently into the output. Use relative_path_from instead:

Suggested change
changed << path.delete_prefix("#{root}/")
changed << Pathname.new(path).relative_path_from(root).to_s

Comment thread bin/test-cpflow-github-flow Outdated
Comment on lines +43 to +46
WORKFLOWS_WITHOUT_CONTROL_PLANE_FLOW_REF = [
".github/workflows/cpflow-help-command.yml",
".github/workflows/cpflow-review-app-help.yml"
].freeze
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This hardcoded allowlist will silently drift as workflows are added, renamed, or removed — a new workflow missing control_plane_flow_ref would falsely pass, and a renamed exempted workflow would start failing.

Consider deriving the exemption from the file content itself: a workflow that contains no uses: shakacode/control-plane-flow line at all legitimately needs no control_plane_flow_ref. That way the guard stays correct without manual maintenance:

# instead of checking an explicit list, skip the check when there are no uses: refs
if input_refs.empty? && uses_refs.any?
  abort "#{path}: missing control_plane_flow_ref for #{expected}"
end

If the two listed workflows genuinely have a uses: line but still don't need the input, add a comment explaining why so the intent survives future edits.

Comment thread bin/test-cpflow-github-flow Outdated
Comment on lines +52 to +55
uses_refs = text.scan(%r{uses:\s+shakacode/control-plane-flow/\.github/workflows/[^@\s]+@([^\s]+)}).flatten
input_refs = text.scan(/^\s*control_plane_flow_ref:\s*(\S+)/).flatten

abort "#{path}: has control_plane_flow_ref but no control-plane-flow reusable workflow" if uses_refs.empty? && input_refs.any?
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor ordering nit: the refs accumulation at line 53 runs even for the empty && empty case (where it's a no-op), then the next at line 55 skips the rest. Moving the next guard before the accumulation makes the control flow easier to follow — "skip this file entirely if there's nothing to track" — without changing behaviour.

Suggested change
uses_refs = text.scan(%r{uses:\s+shakacode/control-plane-flow/\.github/workflows/[^@\s]+@([^\s]+)}).flatten
input_refs = text.scan(/^\s*control_plane_flow_ref:\s*(\S+)/).flatten
abort "#{path}: has control_plane_flow_ref but no control-plane-flow reusable workflow" if uses_refs.empty? && input_refs.any?
next if uses_refs.empty? && input_refs.empty?
(uses_refs + input_refs).each { |ref| refs[ref] << path }

@justin808 justin808 force-pushed the jg-codex/document-cpflow-upstream-testing branch from 1bef2ca to 29aec12 Compare May 23, 2026 20:44
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29aec1267d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +58 to +61
unless uses_match
abort "#{path}:#{job_name} has control_plane_flow_ref but no control-plane-flow reusable workflow" if input_ref

next
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fail when wrapper job lacks a parseable cpflow uses ref

Don’t silently next when uses_match is missing and control_plane_flow_ref is absent, because this lets a broken cpflow-*.yml wrapper pass the new guard entirely. If a reusable-workflow call is edited away from shakacode/control-plane-flow/...@ref (or otherwise becomes unparsable) in a job that doesn’t carry control_plane_flow_ref (for example wrappers without secrets: inherit), this check exits successfully and no ref-consistency error is reported.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bin/test-cpflow-github-flow`:
- Around line 70-71: The guard currently fires for any presence of the secrets
key; change it to only abort when secrets is explicitly set to inherit by
replacing the condition that references job.key?("secrets") with a check that
secrets equals "inherit" (e.g., job["secrets"] == "inherit" or equivalent),
leaving the abort message that mentions control_plane_flow_ref and uses_ref
intact so only jobs with secrets: inherit trigger the missing-ref error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 227fa940-7c9d-4add-ab5a-d4598317fd00

📥 Commits

Reviewing files that changed from the base of the PR and between 1bef2ca and 29aec12.

📒 Files selected for processing (5)
  • .controlplane/docs/testing-cpflow-github-actions.md
  • .controlplane/readme.md
  • .github/testing-github-actions.md
  • bin/pin-cpflow-github-ref
  • bin/test-cpflow-github-flow
✅ Files skipped from review due to trivial changes (1)
  • .controlplane/readme.md

Comment on lines +70 to +71
elsif job.key?("secrets")
abort "#{path}:#{job_name} inherits secrets but is missing control_plane_flow_ref for #{uses_ref}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enforce the missing-ref guard only for secrets: inherit

Line 70 currently triggers on any secrets key, not specifically inherited secrets. That can cause false failures for wrappers that pass explicit secrets mappings.

Suggested fix
-    elsif job.key?("secrets")
+    elsif job["secrets"] == "inherit"
       abort "#{path}:#{job_name} inherits secrets but is missing control_plane_flow_ref for #{uses_ref}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elsif job.key?("secrets")
abort "#{path}:#{job_name} inherits secrets but is missing control_plane_flow_ref for #{uses_ref}"
elsif job["secrets"] == "inherit"
abort "#{path}:#{job_name} inherits secrets but is missing control_plane_flow_ref for #{uses_ref}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bin/test-cpflow-github-flow` around lines 70 - 71, The guard currently fires
for any presence of the secrets key; change it to only abort when secrets is
explicitly set to inherit by replacing the condition that references
job.key?("secrets") with a check that secrets equals "inherit" (e.g.,
job["secrets"] == "inherit" or equivalent), leaving the abort message that
mentions control_plane_flow_ref and uses_ref intact so only jobs with secrets:
inherit trigger the missing-ref error.

@claude
Copy link
Copy Markdown

claude Bot commented May 23, 2026

Code Review: Document cpflow upstream testing

Overall: Low-risk, well-scoped PR. Clear documentation and new scripts address a real operational gap.

What this PR does well

  • The step-by-step guide in .controlplane/docs/testing-cpflow-github-actions.md is precise: names the exact comment body, specifies immutable SHA over branch name, and calls out the CPFLOW_VERSION interaction.
  • bin/pin-cpflow-github-ref correctly rejects moving branch refs by default and requires --allow-moving-ref for local experiments.
  • The rewrite of .github/testing-github-actions.md replaces verbose tab-indented markdown with a tight practical checklist.
  • Fixes Github to GitHub throughout.

Issues

1. Double-entry in refs tracking hash (bin/test-cpflow-github-flow)

When a job has both a valid uses: match and a control_plane_flow_ref, the same path:job_name is appended to refs[uses_ref] twice - once unconditionally, and again inside if input_ref via refs[input_ref] (same key since the values must match when valid). The paths.uniq call in the display compensates, but the internal tracking is inconsistent. See inline comment.

2. gsub pattern can silently strip YAML quotes (bin/pin-cpflow-github-ref)

The replacement pattern \S+ for control_plane_flow_ref matches the entire non-whitespace run. If someone writes the ref as a quoted YAML string, \S+ matches including the surrounding quotes, and the replacement emits a bare unquoted ref. The resulting YAML is still valid but the style change is invisible. See inline comment.

3. FULL_COMMIT_SHA accepts uppercase SHAs (minor)

The /i flag accepts uppercase hex. Git always outputs lowercase SHAs; a 40-char uppercase string would pass validation locally but never resolve to a real upstream object. Consider dropping /i.

4. --help exits with error (minor UX)

--help is treated as an unknown option and exits 1. Recognizing it explicitly would be friendlier for contributors discovering the tool.

Verdict

Approve after addressing items 1 and 2. Items 3 and 4 can be deferred.

refs[uses_ref] << "#{path}:#{job_name}"

if input_ref
refs[input_ref] << "#{path}:#{job_name}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When uses_ref == input_ref (the valid case), refs[uses_ref] already received this path:job_name on line 65. Appending it again here means every valid job appears twice under the same key. paths.uniq in the display compensates, but the double-entry is confusing and could skew refs.length in edge cases.

The mismatch guard on the next line already handles the error case, so this append can be dropped entirely:

Suggested change
refs[input_ref] << "#{path}:#{job_name}"
abort "#{path}:#{job_name} mismatched cpflow refs: #{uses_ref}, #{input_ref}" if uses_ref != input_ref

Comment thread bin/pin-cpflow-github-ref
text = File.read(path)
updated = text
.gsub(%r{(uses:\s+shakacode/control-plane-flow/\.github/workflows/[^@\s]+@)[^\s]+}, "\\1#{ref}")
.gsub(/(\bcontrol_plane_flow_ref:\s*)\S+/, "\\1#{ref}")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

\S+ matches the entire non-whitespace token, including surrounding YAML quotes if the value was written as control_plane_flow_ref: "3e0e7e1f...". The replacement would then emit a bare unquoted ref, silently changing the YAML style.

A tighter pattern that explicitly handles both quoted and unquoted forms would be safer:

Suggested change
.gsub(/(\bcontrol_plane_flow_ref:\s*)\S+/, "\\1#{ref}")
.gsub(/(\bcontrol_plane_flow_ref:\s*)['"]?[0-9A-Za-z._\/-]+['"]?/, "\\1#{ref}")

The generated workflow files currently use unquoted values so this is not an active bug, but it is a latent risk if the generator ever changes style.

@justin808 justin808 merged commit 1fb4cdd into master May 23, 2026
15 checks passed
@justin808 justin808 deleted the jg-codex/document-cpflow-upstream-testing branch May 23, 2026 20:51
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 23, 2026

✅ Review App Deleted

Review app for PR #746 is deleted

🎮 Control Plane Console
📋 View Workflow Logs

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.

1 participant