cpflow 5.0.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/update-changelog.md +88 -23
  3. data/.github/actions/cpflow-resolve-review-config/action.yml +137 -0
  4. data/.github/actions/cpflow-setup-environment/action.yml +118 -0
  5. data/.github/workflows/cpflow-cleanup-stale-review-apps.yml +26 -21
  6. data/.github/workflows/cpflow-delete-review-app.yml +21 -18
  7. data/.github/workflows/cpflow-deploy-review-app.yml +23 -19
  8. data/.github/workflows/cpflow-deploy-staging.yml +15 -11
  9. data/.github/workflows/cpflow-help-command.yml +0 -6
  10. data/.github/workflows/cpflow-promote-staging-to-production.yml +30 -5
  11. data/.github/workflows/cpflow-review-app-help.yml +1 -10
  12. data/CHANGELOG.md +23 -1
  13. data/Gemfile.lock +1 -1
  14. data/docs/ai-github-flow-prompt.md +1 -1
  15. data/docs/ci-automation.md +165 -29
  16. data/lib/command/ai_github_flow_prompt.rb +1 -1
  17. data/lib/cpflow/version.rb +1 -1
  18. data/lib/generator_templates/Dockerfile +1 -0
  19. data/lib/generator_templates/entrypoint.sh +42 -2
  20. data/lib/github_flow_templates/.github/cpflow-help.md +79 -83
  21. data/lib/github_flow_templates/.github/workflows/cpflow-cleanup-stale-review-apps.yml +4 -9
  22. data/lib/github_flow_templates/.github/workflows/cpflow-delete-review-app.yml +2 -9
  23. data/lib/github_flow_templates/.github/workflows/cpflow-deploy-review-app.yml +3 -9
  24. data/lib/github_flow_templates/.github/workflows/cpflow-deploy-staging.yml +3 -8
  25. data/lib/github_flow_templates/.github/workflows/cpflow-help-command.yml +0 -9
  26. data/lib/github_flow_templates/.github/workflows/cpflow-promote-staging-to-production.yml +10 -8
  27. data/lib/github_flow_templates/.github/workflows/cpflow-review-app-help.yml +4 -10
  28. data/lib/github_flow_templates/bin/pin-cpflow-github-ref +3 -1
  29. data/lib/github_flow_templates/bin/test-cpflow-github-flow +23 -8
  30. metadata +2 -1
@@ -23,13 +23,4 @@ jobs:
23
23
  contains(fromJson('["+review-app-help","+review-app-help\n","+review-app-help\r\n"]'), github.event.comment.body) &&
24
24
  contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
25
25
  github.event_name == 'workflow_dispatch'
26
- # control_plane_flow_ref is accepted by the upstream workflow for wrapper
27
- # consistency; this helper checks out caller content only.
28
26
  uses: shakacode/control-plane-flow/.github/workflows/cpflow-help-command.yml@__CPFLOW_GITHUB_ACTIONS_REF__
29
- with:
30
- control_plane_flow_ref: __CPFLOW_GITHUB_ACTIONS_REF__
31
- # `secrets: inherit` passes all caller repository secrets to the trusted
32
- # upstream workflow. This helper does not read them, but GitHub does not
33
- # enforce that boundary. Strict consumers can set CPFLOW_GITHUB_ACTIONS_REF
34
- # to an immutable commit SHA.
35
- secrets: inherit
@@ -16,13 +16,15 @@ permissions:
16
16
  jobs:
17
17
  promote-to-production:
18
18
  if: github.event.inputs.confirm_promotion == 'promote'
19
- # Keep the @ref in `uses:` and `control_plane_flow_ref` below in sync: the
20
- # first selects the reusable workflow, the second selects its shared actions.
21
19
  uses: shakacode/control-plane-flow/.github/workflows/cpflow-promote-staging-to-production.yml@__CPFLOW_GITHUB_ACTIONS_REF__
22
20
  with:
23
- control_plane_flow_ref: __CPFLOW_GITHUB_ACTIONS_REF__
24
- # `secrets: inherit` passes all caller repository secrets to the trusted
25
- # upstream workflow. The upstream workflow only reads the named secrets it
26
- # references, but GitHub does not enforce that boundary. Strict consumers can
27
- # set CPFLOW_GITHUB_ACTIONS_REF to an immutable commit SHA.
28
- secrets: inherit
21
+ # Keep CPLN_TOKEN_PRODUCTION as a secret on this protected GitHub
22
+ # Environment. The caller passes the environment name, the upstream
23
+ # reusable workflow runs its production job in that environment, and
24
+ # GitHub exposes environment secrets only after required reviewers approve.
25
+ production_environment: production
26
+ # Only pass the staging token explicitly. CPLN_TOKEN_PRODUCTION must live on
27
+ # the protected production Environment, where GitHub exposes it only after
28
+ # the required reviewers approve this job.
29
+ secrets:
30
+ CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
@@ -14,14 +14,8 @@ permissions:
14
14
 
15
15
  jobs:
16
16
  show-help:
17
- if: vars.REVIEW_APP_PREFIX != ''
18
- # control_plane_flow_ref is accepted by the upstream workflow for wrapper
19
- # consistency; this helper does not check out shared actions.
17
+ # This is intentionally unconditional: committing this wrapper opts the repo in
18
+ # to PR-open help. Remove it, or uncomment and adapt this guard, if forks or
19
+ # clones should stay quiet until Control Plane is configured:
20
+ # if: vars.REVIEW_APP_PREFIX != '' || vars.CPLN_ORG_STAGING != ''
20
21
  uses: shakacode/control-plane-flow/.github/workflows/cpflow-review-app-help.yml@__CPFLOW_GITHUB_ACTIONS_REF__
21
- with:
22
- control_plane_flow_ref: __CPFLOW_GITHUB_ACTIONS_REF__
23
- # `secrets: inherit` passes all caller repository secrets to the trusted
24
- # upstream workflow. This helper does not read them, but GitHub does not
25
- # enforce that boundary. Strict consumers can set CPFLOW_GITHUB_ACTIONS_REF
26
- # to an immutable commit SHA.
27
- secrets: inherit
@@ -8,6 +8,9 @@ USAGE = <<~USAGE
8
8
 
9
9
  Use a release tag for normal operation, e.g. v5.0.0.
10
10
  Use a full 40-character commit SHA for temporary unreleased upstream testing.
11
+ This only updates generated reusable-workflow `uses:` refs. The called
12
+ workflows load their own matching shared actions from that same workflow
13
+ commit automatically. Regenerate from the cpflow gem when templates changed.
11
14
  Use --allow-moving-ref only for short-lived local branch/ref experiments.
12
15
  USAGE
13
16
 
@@ -56,7 +59,6 @@ workflow_paths.each do |path|
56
59
  text = File.read(path)
57
60
  updated = text
58
61
  .gsub(%r{(uses:\s+shakacode/control-plane-flow/\.github/workflows/[^@\s]+@)[^\s]+}, "\\1#{ref}")
59
- .gsub(/(\bcontrol_plane_flow_ref:\s*)\S+/, "\\1#{ref}")
60
62
 
61
63
  next if updated == text
62
64
 
@@ -43,6 +43,7 @@ ruby <<'RUBY'
43
43
  require "yaml"
44
44
 
45
45
  CONTROL_PLANE_FLOW_WORKFLOW = %r{\Ashakacode/control-plane-flow/\.github/workflows/[^@\s]+@([^\s]+)\z}
46
+ PROMOTE_WORKFLOW = %r{\Ashakacode/control-plane-flow/\.github/workflows/cpflow-promote-staging-to-production\.yml@[^\s]+\z}
46
47
 
47
48
  refs = Hash.new { |hash, key| hash[key] = [] }
48
49
 
@@ -55,21 +56,32 @@ Dir[".github/workflows/cpflow-*.yml"].sort.each do |path|
55
56
  input_ref = with["control_plane_flow_ref"]
56
57
  uses_match = job["uses"].to_s.match(CONTROL_PLANE_FLOW_WORKFLOW)
57
58
 
58
- unless uses_match
59
- abort "#{path}:#{job_name} has control_plane_flow_ref but no control-plane-flow reusable workflow" if input_ref
59
+ if job["secrets"] == "inherit"
60
+ abort "#{path}:#{job_name} uses secrets: inherit; pass only the named secrets the upstream workflow needs"
61
+ end
62
+
63
+ if input_ref
64
+ abort "#{path}:#{job_name} passes obsolete control_plane_flow_ref. Remove it; the upstream reusable workflow checks out its own source from GitHub's job.workflow_* context."
65
+ end
60
66
 
67
+ unless uses_match
61
68
  next
62
69
  end
63
70
 
64
71
  uses_ref = uses_match[1]
65
72
  refs[uses_ref] << "#{path}:#{job_name}"
66
73
 
67
- if input_ref
68
- refs[input_ref] << "#{path}:#{job_name}"
69
- abort "#{path}:#{job_name} mismatched cpflow refs: #{uses_ref}, #{input_ref}" if uses_ref != input_ref
70
- elsif job.key?("secrets")
71
- abort "#{path}:#{job_name} inherits secrets but is missing control_plane_flow_ref for #{uses_ref}"
74
+ if job["uses"].to_s.match?(PROMOTE_WORKFLOW)
75
+ if with["production_environment"].to_s.strip.empty?
76
+ abort "#{path}:#{job_name} must set production_environment so GitHub can expose production environment secrets after approval"
77
+ end
78
+
79
+ secrets = job["secrets"].is_a?(Hash) ? job["secrets"] : {}
80
+ if secrets.key?("CPLN_TOKEN_PRODUCTION")
81
+ abort "#{path}:#{job_name} must not pass CPLN_TOKEN_PRODUCTION as a caller secret; store it on the protected production environment"
82
+ end
72
83
  end
84
+
73
85
  end
74
86
  end
75
87
 
@@ -86,4 +98,7 @@ end
86
98
  RUBY
87
99
 
88
100
  echo "==> actionlint"
89
- actionlint -ignore "SC2129" .github/workflows/cpflow-*.yml
101
+ actionlint \
102
+ -ignore "SC2129" \
103
+ -ignore 'property "workflow_(ref|sha|repository|file_path)" is not defined in object type' \
104
+ .github/workflows/cpflow-*.yml
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -82,6 +82,7 @@ files:
82
82
  - ".github/actions/cpflow-delete-control-plane-app/action.yml"
83
83
  - ".github/actions/cpflow-delete-control-plane-app/delete-app.sh"
84
84
  - ".github/actions/cpflow-detect-release-phase/action.yml"
85
+ - ".github/actions/cpflow-resolve-review-config/action.yml"
85
86
  - ".github/actions/cpflow-setup-environment/action.yml"
86
87
  - ".github/actions/cpflow-validate-config/action.yml"
87
88
  - ".github/actions/cpflow-wait-for-health/action.yml"