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
92 changes: 92 additions & 0 deletions .github/workflows/pending-deploy-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Pending Deploy Check

# This workflow validates that pending deploy PRs are safe to merge.
#
# Trigger: Pull requests to main from automation/pending-deploy-* branches
# Purpose: Verify all commits in the PR have been deployed in managed-service
#
# Why: SDK changes are generated from managed-service OpenAPI specs. We must ensure
# the corresponding managed-service changes have been deployed before merging the SDK changes,
# otherwise the SDK could reference unreleased API features.
#
# Flow:
# 1. For each commit in the PR, extract the Managed-service-commit-SHA trailer
# 2. Check if that SHA is in the latest managed-service release tag
# 3. If any commits are not yet deployed, post a detailed comment and fail the PR

on:
pull_request:
branches: [main]
workflow_dispatch:
inputs:
branch:
description: 'Pending deploy branch to check'
required: true
type: string
pr_url:
description: 'PR URL to comment on if check fails'
required: true
type: string

permissions:
contents: read # Checkout repository and read commit history
pull-requests: write # Post failure comments on PRs

jobs:
pending-deploy-check:
runs-on: ubuntu-latest
if: |
(github.event_name == 'pull_request' && startsWith(github.head_ref, 'automation/pending-deploy-')) ||
(github.event_name == 'workflow_dispatch' && startsWith(inputs.branch, 'automation/pending-deploy-'))
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Validate workflow input
if: github.event_name == 'workflow_dispatch'
id: validate-input
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
source scripts/lib/actions-helpers.sh

# Extract PR number from URL
PR_NUMBER=$(echo "${{ inputs.pr_url }}" | grep -oE '[0-9]+$')
set_output pr_number "$PR_NUMBER"

# Validate the PR's head branch matches the input branch
PR_HEAD_BRANCH=$(gh pr view "$PR_NUMBER" --json headRefName --jq '.headRefName')
if [ "$PR_HEAD_BRANCH" != "${{ inputs.branch }}" ]; then
log_error "PR #$PR_NUMBER head branch ($PR_HEAD_BRANCH) does not match input branch (${{ inputs.branch }})"
exit 1
fi

- name: Run deployment check
id: check-deployment
env:
PENDING_DEPLOY_BRANCH: ${{ inputs.branch || github.head_ref }}
MANAGED_SERVICE_TOKEN: ${{ secrets.MANAGED_SERVICE_TOKEN }}
run: scripts/pending-deploy-check.sh

- name: Post failure comment and fail
if: steps.check-deployment.outputs.has_issues == 'true'
env:
PR_NUMBER: ${{ steps.validate-input.outputs.pr_number || github.event.pull_request.number }}
GITHUB_TOKEN: ${{ github.token }}
run: |
scripts/post-failure-comment.sh
source scripts/lib/actions-helpers.sh
log_error "Deployment check failed - see PR comment for details"
exit 1

- name: Summary
if: always()
run: |
source scripts/lib/actions-helpers.sh
if [ "${{ steps.check-deployment.outputs.has_issues }}" != "true" ]; then
log_info "All commits in pending deploy branch are deployed in managed-service"
else
log_info "Some commits are not deployed or potentially not deployed"
fi
83 changes: 83 additions & 0 deletions .github/workflows/pending-deploy-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Pending Deploy PR

# This workflow creates PRs to apply pending deploy changes to main.
#
# Trigger: workflow_dispatch - called by TeamCity when managed-service is deployed
# Purpose: Automatically create a PR to merge the latest automation/pending-deploy-* branch into main
#
# Flow:
# 1. Find the latest automation/pending-deploy-YYYYMMDD-HHMMSS branch
# 2. Check if it has commits not in main
# 3. Create a PR if one doesn't already exist

on:
workflow_dispatch:
inputs:
timestamp:
description: 'Deployment timestamp'
required: true
type: string
commit_sha:
description: 'Deployed commit SHA'
required: true
type: string

permissions:
contents: read # Checkout repository and read branches/tags
pull-requests: write # Create and update PRs
actions: write # Trigger pending deploy check workflow

jobs:
pending-deploy-pr:
runs-on: ubuntu-latest
outputs:
branch: ${{ steps.create-pr.outputs.branch }}
pr_url: ${{ steps.create-pr.outputs.pr_url }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0 # Need full history to compare branches and commits

- name: Run pending deploy PR workflow
id: create-pr
env:
GITHUB_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: scripts/pending-deploy-pr.sh

# GitHub Actions doesn't automatically trigger workflows when a PR is created using GITHUB_TOKEN
# (to prevent recursive workflow triggers). Since we need deployment validation to run,
# we explicitly dispatch the check workflow here.
- name: Trigger pending deploy check
if: steps.create-pr.outputs.pr_url != '' && steps.create-pr.outputs.branch != ''
id: trigger-check
env:
GH_TOKEN: ${{ github.token }}
run: |
source scripts/lib/actions-helpers.sh
if ! gh workflow run pending-deploy-check.yml \
--repo ${{ github.repository }} \
--field branch="${{ steps.create-pr.outputs.branch }}" \
--field pr_url="${{ steps.create-pr.outputs.pr_url }}"; then
log_error "Failed to trigger pending-deploy-check workflow. You may need to manually trigger the check for ${{ steps.create-pr.outputs.pr_url }}"
else
log_info "Successfully triggered pending-deploy-check workflow"
fi

- name: Summary
if: always()
run: |
source scripts/lib/actions-helpers.sh
if [ -z "${{ steps.create-pr.outputs.branch }}" ]; then
log_info "No pending deploy branches found"
elif [ "${{ steps.create-pr.outputs.has_new_commits }}" != "true" ]; then
log_info "Pending deploy branch has no new commits"
elif [ -n "${{ steps.create-pr.outputs.pr_url }}" ]; then
log_info "PR created or updated for pending deploy branch"
if [ "${{ steps.trigger-check.outcome }}" = "success" ]; then
log_info "Deployment check workflow triggered successfully"
elif [ "${{ steps.trigger-check.outcome }}" = "failure" ]; then
log_info "Failed to trigger deployment check workflow"
fi
fi
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Automated pending deploy branch management with two GitHub Actions workflows:
- `pending-deploy-pr.yml`: Creates PRs from pending deploy branches to main (triggered via
workflow_dispatch) and triggers a pending deploy check
- `pending-deploy-check.yml`: Validates that SDK commits reference deployed managed-service changes
before allowing merge
- Automated release workflow that creates release PRs when `automation/pending-deploy-*`
branches are merged to main, updating the version number in all relevant files
- Added pending deploy branch management to release workflow to ensure automated
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ add-boilerplate:
validate:
go run main.go

# Run bash helper script tests
.PHONY: test-scripts
test-scripts:
./scripts/run-tests.sh

default: generate-openapi-client validate

# build-tool is a helper that builds $TOOL_PKG in a temp directory so that it
Expand Down
Loading
Loading