Skip to content
Open
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
2 changes: 2 additions & 0 deletions .agents/agent-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
base_branch: master
merge_submission:
mode: direct
trusted_actions:
- shakacode/control-plane-flow
follow_up_prefix: 'Follow-up:'
review_gate: n/a
approval_exempt: n/a
Expand Down
5 changes: 5 additions & 0 deletions .controlplane/controlplane.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,10 @@ apps:
<<: *common
# match_if_app_name_starts_with is used to identify these "qa" apps.
match_if_app_name_starts_with: true
# These review-app one-off defaults request app-sized resources and set a
# 15-minute server-side active deadline.
runner_job_default_cpu: "300m"
runner_job_default_memory: "1Gi"
runner_job_timeout: 900
Comment thread
justin808 marked this conversation as resolved.
Comment thread
justin808 marked this conversation as resolved.
image_retention_days: 5
stale_app_image_deployed_days: 5 # If the app is older than 5 days, the nightly automations will clean stale apps.
2 changes: 1 addition & 1 deletion .github/workflows/cpflow-deploy-review-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
github.event.issue.pull_request &&
contains(fromJson('["+review-app-deploy","+review-app-deploy\n","+review-app-deploy\r\n"]'), github.event.comment.body) &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-review-app.yml@v5.2.0
uses: shakacode/control-plane-flow/.github/workflows/cpflow-deploy-review-app.yml@b8676066d3344098bef8e35ee4abce1d0ca9d8a3 # unreleased control-plane-flow PR #435 revision
Comment thread
justin808 marked this conversation as resolved.
secrets:
CPLN_TOKEN_STAGING: ${{ secrets.CPLN_TOKEN_STAGING }}
DOCKER_BUILD_SSH_KEY: ${{ secrets.DOCKER_BUILD_SSH_KEY }}
52 changes: 42 additions & 10 deletions bin/test-cpflow-github-flow
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,13 @@ PROMOTE_WORKFLOW = %r{\Ashakacode/control-plane-flow/\.github/workflows/cpflow-p
EXPECTED_PROMOTE_WORKFLOW_REF_FORMAT = "shakacode/control-plane-flow/.github/workflows/cpflow-promote-staging-to-production.yml@vX.Y.Z"
EXPECTED_CPFLOW_CHECKOUT_ACTION = "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd"
EXPECTED_CPFLOW_CHECKOUT_REPOSITORY = "shakacode/control-plane-flow"
REVIEW_APP_CANARY_PATH = ".github/workflows/cpflow-deploy-review-app.yml"
REVIEW_APP_CANARY_JOB = "deploy"
REVIEW_APP_CANARY_WORKFLOW = "shakacode/control-plane-flow/.github/workflows/cpflow-deploy-review-app.yml"
FULL_COMMIT_SHA = /\A[0-9a-f]{40}\z/i

refs = Hash.new { |hash, key| hash[key] = [] }
stable_refs = Hash.new { |hash, key| hash[key] = [] }
review_app_canary_entries = []

Dir[".github/workflows/cpflow-*.yml"].sort.each do |path|
doc = YAML.load_file(path, aliases: true)
Expand All @@ -157,7 +162,17 @@ Dir[".github/workflows/cpflow-*.yml"].sort.each do |path|
end

uses_ref = uses_match[1]
refs[uses_ref] << "#{path}:#{job_name}"
entry = "#{path}:#{job_name}"
if path == REVIEW_APP_CANARY_PATH && job_name == REVIEW_APP_CANARY_JOB
canary_workflow = job["uses"].to_s.delete_suffix("@#{uses_ref}")
unless canary_workflow == REVIEW_APP_CANARY_WORKFLOW
abort "#{entry} must call #{REVIEW_APP_CANARY_WORKFLOW}, got #{canary_workflow.inspect}"
end

review_app_canary_entries << { ref: uses_ref, entry: entry }
else
stable_refs[uses_ref] << entry
end

if job["uses"].to_s.match?(PROMOTE_WORKFLOW)
abort "#{path}:#{job_name} must not call the cross-repo production reusable workflow; use a normal caller-repo job with environment: production"
Expand Down Expand Up @@ -204,7 +219,7 @@ if checkout_ref.to_s.strip.empty?
abort "#{promote_path}:promote-to-production must pin the Checkout control-plane-flow actions step"
end

refs[checkout_ref] << "#{promote_path}:promote-to-production"
stable_refs[checkout_ref] << "#{promote_path}:promote-to-production"

setup_step = Array(promote_job["steps"]).find { |step| step["name"] == "Setup production environment" }

Expand All @@ -220,17 +235,34 @@ unless setup_match
"for example #{EXPECTED_PROMOTE_WORKFLOW_REF_FORMAT}"
end

refs[setup_match[1]] << "#{promote_path}:promote-to-production setup"
stable_refs[setup_match[1]] << "#{promote_path}:promote-to-production setup"

unless review_app_canary_entries.length == 1
abort "expected exactly one review-app canary entry at #{REVIEW_APP_CANARY_PATH}:#{REVIEW_APP_CANARY_JOB}, " \
"found #{review_app_canary_entries.length}"
end

if refs.empty?
puts "no upstream cpflow reusable workflow refs found"
elsif refs.length > 1
refs.each do |ref, paths|
if stable_refs.empty?
abort "no stable upstream cpflow refs found outside the review-app canary"
elsif stable_refs.length > 1
stable_refs.each do |ref, paths|
puts "#{ref}: #{paths.uniq.sort.join(', ')}"
end
abort "cpflow workflow wrappers use multiple upstream refs: #{refs.keys.sort.join(', ')}"
abort "non-canary cpflow workflow wrappers use multiple upstream refs: #{stable_refs.keys.sort.join(', ')}"
end

stable_ref = stable_refs.keys.fetch(0)
review_app_canary = review_app_canary_entries.fetch(0)
review_app_ref = review_app_canary.fetch(:ref)

if review_app_ref == stable_ref
puts "cpflow refs: #{stable_ref}"
elsif review_app_ref.match?(FULL_COMMIT_SHA)
puts "cpflow stable ref: #{stable_ref}"
puts "review-app canary ref: #{review_app_ref} (#{review_app_canary.fetch(:entry)})"
else
puts "cpflow refs: #{refs.keys.sort.join(', ')}"
abort "review-app canary may diverge from #{stable_ref} only with a full 40-character commit SHA, " \
"got #{review_app_ref.inspect}"
end
RUBY

Expand Down
Loading