Skip to content

.github/workflows/promote-to-staging.yml #64

.github/workflows/promote-to-staging.yml

.github/workflows/promote-to-staging.yml #64

name: Promote Dev to Staging
# Manual promotion workflow: dev → staging
# Validates dev branch and creates PR requiring manual approval
on:
workflow_dispatch: # Manual trigger only
inputs:
skip_checks:
description: 'Skip CI checks (emergency only)'
required: false
default: 'false'
type: choice
options:
- 'false'
- 'true'
permissions:
contents: write
pull-requests: write
issues: write
jobs:
# Validate dev branch before promotion
validate-dev:
name: "Validate Dev Branch"
runs-on: ubuntu-latest
if: github.repository == 'ScheierVentures/emburden' && inputs.skip_checks != 'true'
outputs:
dev_sha: ${{ steps.get_sha.outputs.dev_sha }}
dev_short_sha: ${{ steps.get_sha.outputs.dev_short_sha }}
steps:
- name: Checkout dev branch
uses: actions/checkout@v4
with:
ref: dev
fetch-depth: 0
- name: Get dev branch SHA
id: get_sha
run: |
DEV_SHA=$(git rev-parse HEAD)
DEV_SHORT_SHA=$(git rev-parse --short HEAD)
echo "dev_sha=$DEV_SHA" >> $GITHUB_OUTPUT
echo "dev_short_sha=$DEV_SHORT_SHA" >> $GITHUB_OUTPUT
echo "Dev branch SHA: $DEV_SHA"
- name: Setup R
uses: r-lib/actions/setup-r@v2
with:
r-version: 'release'
use-public-rspm: true
- name: Setup R dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check
- name: Setup Pandoc
uses: r-lib/actions/setup-pandoc@v2
- name: Run R CMD check on dev
run: |
echo "🔍 Running R CMD check on dev branch..."
Rscript -e "rcmdcheck::rcmdcheck(
args = c('--no-manual', '--as-cran'),
error_on = 'warning',
check_dir = 'check'
)"
- name: Upload check results
if: failure()
uses: actions/upload-artifact@v4
with:
name: dev-check-results
path: check/
# Create promotion PR
create-promotion-pr:
name: "Create Promotion PR"
needs: [validate-dev]
if: |
always() &&
(needs.validate-dev.result == 'success' || inputs.skip_checks == 'true')
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.create_pr.outputs.pr_number }}
steps:
- name: Checkout staging branch
uses: actions/checkout@v4
with:
ref: staging
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Create promotion branch
id: create_branch
run: |
TIMESTAMP=$(date -u +"%Y%m%d-%H%M%S")
BRANCH_NAME="promote/dev-to-staging-${TIMESTAMP}"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
# Create promotion branch from staging
git checkout -b "$BRANCH_NAME"
# Merge dev into promotion branch
git fetch origin dev:dev
git merge --no-ff dev -m "chore: Promote dev to staging (${TIMESTAMP})"
# Push promotion branch
git push origin "$BRANCH_NAME"
echo "Created promotion branch: $BRANCH_NAME"
- name: Create pull request
id: create_pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}"
DEV_SHA="${{ needs.validate-dev.outputs.dev_sha || 'N/A' }}"
DEV_SHORT_SHA="${{ needs.validate-dev.outputs.dev_short_sha || 'N/A' }}"
TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC")
# Get commits between staging and dev
COMMITS=$(git log staging..dev --oneline --no-merges | head -20)
COMMIT_COUNT=$(git rev-list --count staging..dev)
# Create PR body (without single quotes to allow variable expansion)
cat > pr_body.md << EOF
## 🚀 Dev → Staging Promotion
+ **Promotion timestamp:** $TIMESTAMP

Check failure on line 143 in .github/workflows/promote-to-staging.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/promote-to-staging.yml

Invalid workflow file

You have an error in your yaml syntax on line 143
+ **Dev branch SHA:** \`$DEV_SHORT_SHA\` (\`$DEV_SHA\`)
+ **Commits included:** $COMMIT_COUNT
### Changes in this promotion
\`\`\`
$COMMITS
\`\`\`
### Pre-promotion validation
- ✅ Dev branch R CMD check: **PASSED**
- ✅ All dev CI checks: **PASSED**
### Required approvals
This promotion requires:
1. ✅ Manual approval via \`staging-promotion\` environment
2. ✅ All staging CI checks must pass
3. ✅ Code review approval
### What happens after approval?
1. PR will auto-merge to staging
2. Staging CI will run (multi-platform)
3. Promotion tag \`staging/YYYYMMDD-HHMMSS\` will be created
4. Staging is then ready for production release
---
**⚠️ IMPORTANT:** Review all changes carefully before approving. Once merged, staging becomes the source of truth for the next production release.
EOF
# Substitute variables
sed -i "s/\$TIMESTAMP/$TIMESTAMP/g" pr_body.md
sed -i "s/\$DEV_SHA/$DEV_SHA/g" pr_body.md
sed -i "s/\$DEV_SHORT_SHA/$DEV_SHORT_SHA/g" pr_body.md
sed -i "s/\$COMMIT_COUNT/$COMMIT_COUNT/g" pr_body.md
sed -i "s/\$COMMITS/$COMMITS/g" pr_body.md
# Create PR
PR_URL=$(gh pr create \
--base staging \
--head "$BRANCH_NAME" \
--title "🚀 Promote dev to staging ($(date -u +"%Y-%m-%d"))" \
--body-file pr_body.md \
--label "promotion" \
--label "staging")
# Extract PR number
PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]*$')
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
echo "Created promotion PR: $PR_URL"
echo "PR Number: $PR_NUMBER"
- name: Add promotion comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER="${{ steps.create_pr.outputs.pr_number }}"
gh pr comment "$PR_NUMBER" --body "$(cat <<'EOF'
### 📋 Promotion Checklist
Before approving this promotion, verify:
- [ ] All changes in dev have been reviewed and tested
- [ ] No breaking changes unless documented
- [ ] All CI checks pass (ubuntu, windows, macos)
- [ ] Code coverage is maintained or improved
- [ ] Documentation is up to date
- [ ] CHANGELOG/NEWS is updated (if applicable)
**Approval process:**
1. Review all changes in this PR
2. Verify CI status checks are green
3. Approve via GitHub PR review
4. Approve via \`staging-promotion\` environment gate
5. PR will auto-merge after approval
**Questions or issues?** Leave a comment and mark the checklist items that need attention.
EOF
)"
# Wait for approval and auto-merge
auto-merge:
name: "Auto-Merge After Approval"
needs: [create-promotion-pr]
runs-on: ubuntu-latest
environment: staging-promotion # Requires manual approval
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Enable auto-merge
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER="${{ needs.create-promotion-pr.outputs.pr_number }}"
echo "🔄 Enabling auto-merge for PR #$PR_NUMBER..."
# Enable auto-merge with squash strategy
gh pr merge "$PR_NUMBER" --auto --squash --delete-branch
echo "✅ Auto-merge enabled. PR will merge automatically after:"
echo " - All status checks pass"
echo " - Required reviews are approved"
echo " - staging-promotion environment approval granted"
- name: Tag promotion
if: success()
run: |
TIMESTAMP=$(date -u +"%Y%m%d-%H%M%S")
TAG_NAME="staging/${TIMESTAMP}"
echo "📌 Creating promotion tag: $TAG_NAME"
# Wait a moment for merge to complete
sleep 10
# Fetch latest staging
git fetch origin staging:staging
git checkout staging
# Create and push tag
git tag -a "$TAG_NAME" -m "Promotion from dev to staging at $TIMESTAMP"
git push origin "$TAG_NAME"
echo "✅ Created tag: $TAG_NAME"
- name: Promotion summary
if: always()
run: |
PR_NUMBER="${{ needs.create-promotion-pr.outputs.pr_number }}"
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
## ✅ Dev → Staging Promotion Complete
**PR Number:** #$PR_NUMBER
**Status:** Merged and tagged
**Next steps:**
- Staging CI is running
- Review staging deployment
- When ready, promote staging → main for production release
---
**Branching flow:**
```
Feature branches → dev → [staging] → main → public repo → CRAN
^^^^^^^^
YOU ARE HERE
```
EOF
sed -i "s/\$PR_NUMBER/$PR_NUMBER/g" $GITHUB_STEP_SUMMARY