Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/manifest.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ci:
config:
trunk_branch: main
state_token: ${{ secrets.CASCADE_STATE_TOKEN }}
triggers:
- cmd/**
- internal/**
Expand Down
55 changes: 46 additions & 9 deletions .github/workflows/orchestrate.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# AUTO-GENERATED by cascade - DO NOT EDIT MANUALLY
# Regenerate with: cascade generate-workflow --config .github/manifest.yaml
# Regenerate with: cascade generate-workflow --config /Users/joshua.temple/go/src/github.com/stablekernel/cascade/.worktrees/activate/.github/manifest.yaml

name: Orchestrate CI/CD

Expand Down Expand Up @@ -31,6 +31,7 @@ jobs:
setup:
name: Setup
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
run_build_cli: ${{ steps.setup.outputs.run_build_cli }}
head_sha: ${{ steps.setup.outputs.head_sha }}
Expand Down Expand Up @@ -76,6 +77,7 @@ jobs:
needs: [setup, validate, build-cli]
if: always() && needs.setup.result == 'success'
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
cli_result: ${{ needs.build-cli.outputs.result }}
validate_result: ${{ needs.validate.outputs.result }}
Expand Down Expand Up @@ -148,6 +150,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Update Manifest
env:
GH_TOKEN: ${{ secrets.CASCADE_STATE_TOKEN }}
HEAD_SHA: ${{ needs.setup.outputs.head_sha }}
VERSION: ${{ needs.setup.outputs.version }}
run: |
Expand All @@ -171,6 +174,33 @@ jobs:
yq eval -i ".$MANIFEST_KEY.state.prerelease.committed_by = \"${{ github.actor }}\"" "$MANIFEST_FILE"
}

if [[ "$GITHUB_SERVER_URL" != "https://github.com" ]]; then
# act/gitea e2e: no GitHub API, and the trunk is neither protected nor
# signature-checked, so push the state commit directly with retries.
for attempt in 1 2 3 4 5; do
git fetch origin "$BRANCH"
git reset --hard "origin/$BRANCH"
apply_state_edits
if git diff --quiet "$MANIFEST_FILE"; then
echo "No state changes"
exit 0
fi
git add "$MANIFEST_FILE"
git commit -m "chore: update state [skip ci]"
if git push origin "HEAD:$BRANCH"; then
echo "Pushed state on attempt $attempt"
exit 0
fi
echo "Push attempt $attempt rejected (likely concurrent run); retrying..." >&2
sleep $((RANDOM % 5 + 2))
done
echo "::error::Failed to push state after 5 attempts" >&2
exit 1
fi

# Real GitHub: write state through the Contents REST API. API commits are
# signed by GitHub (Verified) and, with a bypass-capable token, update the
# trunk even when a required status check protects it.
for attempt in 1 2 3 4 5; do
git fetch origin "$BRANCH"
git reset --hard "origin/$BRANCH"
Expand All @@ -179,19 +209,26 @@ jobs:
echo "No state changes"
exit 0
fi
git add "$MANIFEST_FILE"
git commit -m "chore: update state [skip ci]"
if git push origin "HEAD:$BRANCH"; then
echo "Pushed state on attempt $attempt"
CONTENT_B64=$(base64 -w0 "$MANIFEST_FILE" 2>/dev/null || base64 "$MANIFEST_FILE" | tr -d '\n')
CURRENT_SHA=$(gh api "repos/${{ github.repository }}/contents/$MANIFEST_FILE?ref=$BRANCH" --jq '.sha' 2>/dev/null || true)
API_ARGS=("repos/${{ github.repository }}/contents/$MANIFEST_FILE" -X PUT
-f "message=chore: update state [skip ci]"
-f "content=$CONTENT_B64"
-f "branch=$BRANCH")
if [[ -n "$CURRENT_SHA" ]]; then
API_ARGS+=(-f "sha=$CURRENT_SHA")
fi
if gh api "${API_ARGS[@]}" >/dev/null; then
echo "Pushed state via API on attempt $attempt"
exit 0
fi
echo "Push attempt $attempt rejected (likely concurrent run); retrying..." >&2
echo "State write attempt $attempt failed (likely concurrent run); retrying..." >&2
sleep $((RANDOM % 5 + 2))
done
echo "::error::Failed to push state after 5 attempts" >&2
echo "::error::Failed to write state via API after 5 attempts" >&2
exit 1
- name: Check for Failures
if: needs.validate.result == 'failure' || needs.build-cli.result == 'failure'
if: contains(fromJSON('["failure", "cancelled"]'), needs.validate.result) || contains(fromJSON('["failure", "cancelled"]'), needs.build-cli.result)
run: |
echo "One or more critical callbacks failed"
echo "One or more critical callbacks failed or were cancelled"
exit 1
5 changes: 5 additions & 0 deletions .github/workflows/promote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ permissions:
contents: write
actions: write

concurrency:
group: "${{ github.workflow }}"
cancel-in-progress: false

jobs:
preflight:
name: Pre-flight Check
Expand Down Expand Up @@ -269,6 +273,7 @@ jobs:
- name: Finalize Promotion
if: ${{ github.event.inputs.dry_run != 'true' }}
env:
GH_TOKEN: ${{ secrets.CASCADE_STATE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROMOTION_RESULT: ${{ needs.preflight.outputs.promotion_result }}
run: |
Expand Down
Loading