GitHub Actions一直在使用develop分支的最新提交,而不是main分支的提交
使用这个简单的GitHub Actions工作流:
name: Deploy to Production
on:
workflow_run:
workflows: [ "CI - Tests & Quality" ]
types: [ completed ]
branches: [ main ]
workflow_dispatch:
inputs:
skip_tests:
description: 'Skip test requirement (emergency only)'
required: false
type: boolean
default: false
env:
DEPLOY_PATH: ${{ vars.PRODUCTION_PATH }}
jobs:
pre-deploy-checks:
name: Pre-deployment Checks
runs-on: ubuntu-latest
if: |
github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch'
outputs:
deployment-id: ${{ steps.prepare.outputs.deployment_id }}
steps:
- name: Prepare deployment with branch validation
id: prepare
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
COMMIT_SHA="${{ github.sha }}"
BRANCH="main"
else
WORKFLOW_BRANCH="${{ github.event.workflow_run.head_branch }}"
if [ "$WORKFLOW_BRANCH" != "main" ]; then
echo "❌ Deployment cancelled: CI workflow ran on branch '${WORKFLOW_BRANCH}', not 'main'"
exit 1
fi
COMMIT_SHA="${{ github.event.workflow_run.head_sha }}"
BRANCH="$WORKFLOW_BRANCH"
fi
DEPLOYMENT_ID="deploy-$(date +%Y%m%d-%H%M%S)-${COMMIT_SHA::7}"
echo "deployment_id=${DEPLOYMENT_ID}" >> $GITHUB_OUTPUT
echo "commit_sha=${COMMIT_SHA}" >> $GITHUB_OUTPUT
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
echo "🚀 Starting deployment: ${DEPLOYMENT_ID}"
echo "📦 Branch: ${BRANCH}"
echo "📦 Commit: ${COMMIT_SHA}"
deploy:
name: Deploy to Production Server
needs: pre-deploy-checks
runs-on: self-hosted
timeout-minutes: 10
steps:
- name: Set deployment variables
run: |
echo "DEPLOYMENT_ID=${{ needs.pre-deploy-checks.outputs.deployment-id }}" >> $GITHUB_ENV
echo "TIMESTAMP=$(date +%Y%m%d_%H%M%S)" >> $GITHUB_ENV
echo "CURRENT_USER=$(whoami)" >> $GITHUB_ENV
它是由其他工作流触发的:
name: CI - Tests & Quality
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_run:
workflows: [ "Build Docker Image" ]
types: [ completed ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
部署到生产环境时仍然使用我develop分支上最后一次提交的提交哈希,而不是main分支的提交。
如何才能确认它使用的是正确的分支?
解决方案
我认为生产工作流并不总是会选用最新的main提交,因为它是通过workflow_run触发的。CI工作流可以来自多种来源,比如main、develop、PRs,以及在Docker构建工作流之后触发。因此,即使生产工作流配置为针对main,它仍可能接收到来自另一个分支或较旧SHA的前一个工作流上下文。
为了确保安全,不应在部署工作流中依赖默认的github.sha。相反,应明确部署通过前一个工作流的确切提交,使用:
github.event.workflow_run.head_sha
修复步骤:
步骤1:在生产工作流中添加调试日志。
- name: Debug workflow
run: |
echo "event_name=${{ github.event_name }}"
echo "head_branch=${{ github.event.workflow_run.head_branch }}"
echo "head_sha=${{ github.event.workflow_run.head_sha }}"
echo "github_ref=${{ github.ref }}"
echo "github_sha=${{ github.sha }}"
步骤2:在部署前添加分支检查 确保只有当完成的CI工作流来自main分支时,生产才会运行。
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main'
步骤3:检出通过CI的确切提交 不要让检出使用默认的SHA,而要显式检出经过测试的提交。
- name: Checkout exact tested commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
步骤4:同样限制上游工作流 如果CI工作流是由像Docker构建这样的其他工作流触发的,那么该触发也应限制为main。
on:
workflow_run:
workflows: ["Build Docker Image"]
types: [completed]
branches: [main]
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。