You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS CodePipeline/CodeBuild中实现[skip ci]提交消息检测

实现AWS CodePipeline(GitHub Connections源)的[skip ci]功能

我使用配置了GitHub Connections源的AWS CodePipeline将Python应用部署至AWS Elastic Beanstalk,希望实现类似GitHub Actions的[skip ci]功能——通过检测提交消息中的特定前缀,提前终止构建阶段。

尝试在buildspec.yml中添加git命令获取提交消息,但因CodeBuild环境目录并非Git仓库而失败,报错如下:

version: 0.2

env:
  git-credential-helper: yes

phases:
  install:
    runtime-versions:
      python: 3.12
    commands:
      - COMMIT_MESSAGE=$(git log -1 --pretty=%B)
      - if [[ "$COMMIT_MESSAGE" == *"[skip ci]"* ]]; then echo "Skipping build"; exit 0; fi
fatal: not a git repository (or any parent up to mount point /codebuild)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

[Container] 2025/04/09 18:15:33.812706 Command did not exit successfully COMMIT_MESSAGE=$(git log -1 --pretty=%B) exit status 128
[Container] 2025/04/09 18:15:33.846916 Phase complete: INSTALL State: FAILED
[Container] 2025/04/09 18:15:33.846931 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: COMMIT_MESSAGE=$(git log -1 --pretty=%B). Reason: exit status 128

以下是可行的解决方案:

一、通过GitHub API在CodeBuild中获取提交消息

GitHub Connections源的CodePipeline会自动将提交SHA注入到CodeBuild的CODEBUILD_SOURCE_VERSION环境变量中。利用这个SHA,结合GitHub API即可获取提交消息。

修改后的buildspec.yml:

version: 0.2

env:
  git-credential-helper: yes
  # 从Secrets Manager读取GitHub Token(需提前存储具有仓库读取权限的Token)
  secrets-manager:
    GITHUB_TOKEN: "github:personal_access_token"

phases:
  install:
    runtime-versions:
      python: 3.12
    commands:
      - # 替换为你的GitHub用户名和仓库名
      - REPO_FULL_NAME="your-username/your-repo"
      - # 调用GitHub API获取提交消息
      - COMMIT_MESSAGE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$REPO_FULL_NAME/commits/$CODEBUILD_SOURCE_VERSION" | jq -r '.commit.message')
      - # 检测[skip ci]前缀并终止构建
      - if [[ "$COMMIT_MESSAGE" == *"[skip ci]"* ]]; then echo "Skipping build due to [skip ci] in commit message"; exit 0; fi

注意:需为CodeBuild服务角色添加访问Secrets Manager的权限,确保GitHub Token拥有仓库读取权限。

二、添加Lambda预构建检查(推荐方案)

在CodePipeline的源阶段之后、构建阶段之前插入Lambda函数,提前检查提交消息并决定是否跳过后续阶段。

1. Lambda函数代码(Python)

import boto3
import json
import urllib3

def lambda_handler(event, context):
    job_id = event['CodePipeline.job']['id']
    codepipeline = boto3.client('codepipeline')
    
    # 从S3获取源工件的元数据文件(GitHub Connections自动生成)
    input_artifact = event['CodePipeline.job']['data']['inputArtifacts'][0]
    s3_bucket = input_artifact['location']['s3Location']['bucketName']
    s3_key = f"{input_artifact['location']['s3Location']['objectKey']}.metadata.json"
    
    s3 = boto3.client('s3')
    metadata_obj = s3.get_object(Bucket=s3_bucket, Key=s3_key)
    metadata = json.loads(metadata_obj['Body'].read().decode('utf-8'))
    
    # 提取提交SHA和仓库信息
    commit_sha = metadata['version']
    repo_full_name = metadata['repository']['full_name']
    
    # 调用GitHub API获取提交消息
    http = urllib3.PoolManager()
    headers = {'Authorization': 'token YOUR_GITHUB_PERSONAL_TOKEN'}
    url = f"https://api.github.com/repos/{repo_full_name}/commits/{commit_sha}"
    response = http.request('GET', url, headers=headers)
    commit_data = json.loads(response.data.decode('utf-8'))
    commit_message = commit_data['commit']['message']
    
    # 判断是否跳过CI
    if '[skip ci]' in commit_message:
        codepipeline.put_job_success_result(
            jobId=job_id,
            message="Skipping CI: [skip ci] detected in commit message"
        )
        return {"statusCode": 200}
    else:
        codepipeline.put_job_success_result(
            jobId=job_id,
            message="Proceeding with CI: no skip flag detected"
        )
        return {"statusCode": 200}

2. CodePipeline配置调整

  • 在Pipeline中新增Invoke阶段,放置于源阶段与构建阶段之间
  • 选择上述Lambda函数作为执行角色
  • 确保Lambda角色拥有以下权限:
    • codepipeline:PutJobSuccessResult、codepipeline:PutJobFailureResult
    • s3:GetObject(针对Pipeline工件存储桶)
    • 网络权限允许访问GitHub API

3. 构建阶段配合(可选)

若需在构建阶段再次确认,可在buildspec.yml中添加逻辑:

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.12
    commands:
      - # 若Lambda通过Pipeline变量传递跳过标记,可在此判断
      - if [[ "${SKIP_CI:-false}" == "true" ]]; then echo "Skipping build"; exit 0; fi

三、自定义Webhook触发流水线

放弃GitHub Connections,改用自定义Lambda Webhook接收GitHub推送事件,仅当提交消息不含[skip ci]时触发CodePipeline。

Webhook核心逻辑示例:

import boto3
import json

def lambda_handler(event, context):
    payload = json.loads(event['body'])
    commit_message = payload['commits'][0]['message']
    
    if '[skip ci]' not in commit_message:
        codepipeline = boto3.client('codepipeline')
        codepipeline.start_pipeline_execution(
            name='Your-Pipeline-Name'
        )
    return {"statusCode": 200}

需在GitHub仓库中配置Webhook,指向Lambda的API Gateway端点,并确保Lambda拥有codepipeline:StartPipelineExecution权限。

内容的提问来源于stack exchange,提问作者Gabriel Tkacz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:14:51