配置AWS CodePipeline后Bitbucket未显示分支/构建状态,缺什么?
问题:Bitbucket无法显示AWS CodePipeline分支及构建状态,缺少哪些配置?
我通过以下AWS CDK代码实现了连接Bitbucket的AWS CodePipeline,期望在Bitbucket平台上显示分支及构建状态,但尝试后未成功。请问还缺少哪些必要配置?
import { CfnOutput, Duration, RemovalPolicy } from 'aws-cdk-lib' import * as codebuild from 'aws-cdk-lib/aws-codebuild' import * as codepipeline from 'aws-cdk-lib/aws-codepipeline' import * as codepipeline_actions from 'aws-cdk-lib/aws-codepipeline-actions' import * as events from 'aws-cdk-lib/aws-events' import * as targets from 'aws-cdk-lib/aws-events-targets' import * as iam from 'aws-cdk-lib/aws-iam' import * as lambda from 'aws-cdk-lib/aws-lambda' import * as s3 from 'aws-cdk-lib/aws-s3' import { Construct } from 'constructs' import { StackContext, use } from 'sst/constructs' import { BITBUCKET_BRANCH, BITBUCKET_OWNER, BITBUCKET_REPO } from './config' import { Connections } from './connections' export interface BasePipelineProps { app: StackContext['app'] stack: StackContext['stack'] baseName: string pullRequests?: boolean branch?: string triggerOnPush?: boolean } export class BasePipeline extends Construct { pipeline: codepipeline.Pipeline buildRole: iam.Role sourceOutput: codepipeline.Artifact sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction pipelineRole: iam.Role constructor(scope: Construct, id: string, props: BasePipelineProps) { super(scope, id) const { app, stack, triggerOnPush = true } = props const baseName = app.logicalPrefixedName(props.baseName) this.sourceOutput = new codepipeline.Artifact(`${baseName}SourceOutput`) const branch = props.branch ?? BITBUCKET_BRANCH this.buildRole = new iam.Role(stack, `${baseName}CodeBuildRole`, { assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'), }) const { connectionArn, connectionPolicy } = use(Connections) this.buildRole.addToPolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: [ 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents', 's3:GetBucketAcl', 's3:GetBucketLocation', 's3:GetObject', 's3:GetObjectVersion', 's3:PutObject', 'sts:AssumeRole', ], resources: ['*'], }), ) // Grant permissions to the build role this.buildRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess')) // Create Pipeline role this.pipelineRole = new iam.Role(stack, `${baseName}CodePipelineRole`, { assumedBy: new iam.ServicePrincipal('codepipeline.amazonaws.com'), }) this.pipelineRole.addToPolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: [ 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents', 's3:GetObject', 's3:GetObjectVersion', 's3:GetBucketVersioning', 's3:PutObject', 'codebuild:BatchGetBuilds', 'codebuild:StartBuild', 'codebuild:StopBuild', 'codestar-connections:UseConnection', 'codestar-connections:GetConnection', 'codestar-connections:PassConnection', ], resources: ['*'], }), ) this.pipelineRole.addManagedPolicy(connectionPolicy) this.sourceAction = new codepipeline_actions.CodeStarConnectionsSourceAction({ actionName: 'Source', owner: BITBUCKET_OWNER, repo: BITBUCKET_REPO, branch: branch, output: this.sourceOutput, connectionArn: connectionArn, triggerOnPush, variablesNamespace: 'pipeVariables', codeBuildCloneOutput: true, role: this.pipelineRole, }) // create the artifact bucket const artifactBucket = new s3.Bucket(stack, `${baseName}ArtifactBucket`, { versioned: true, removalPolicy: RemovalPolicy.DESTROY, autoDeleteObjects: true, }) // Create Pipeline this.pipeline = new codepipeline.Pipeline(stack, `${baseName}Pipeline`, { pipelineType: codepipeline.PipelineType.V2, pipelineName: `${baseName}-pipeline`, crossAccountKeys: true, restartExecutionOnUpdate: true, executionMode: codepipeline.ExecutionMode.PARALLEL, role: this.pipelineRole, artifactBucket, ...(props.pullRequests && { triggers: [ { providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, gitConfiguration: { sourceAction: this.sourceAction, pullRequestFilter: [ { events: [codepipeline.GitPullRequestEvent.OPEN, codepipeline.GitPullRequestEvent.UPDATED], branchesIncludes: [branch], }, ], }, }, ], }), }) // Create Lint Project const lintProject = new codebuild.PipelineProject(stack, `${baseName}LintProject`, { buildSpec: codebuild.BuildSpec.fromObject({ version: '0.2', phases: { install: { 'runtime-versions': { nodejs: '20', }, commands: ['npm install -g pnpm', 'pnpm install --store-dir=/root/.pnpm-store'], }, build: { commands: ['pnpm lint'], }, }, cache: { paths: ['node_modules/**/*', '**/node_modules/**/*', 'web/.next/cache/**/*', '/root/.pnpm-store/**/*'], }, }), environment: { buildImage: codebuild.LinuxBuildImage.STANDARD_7_0, privileged: true, environmentVariables: { DOCKER: { value: 'true' }, NODE_OPTIONS: { value: '--max_old_space_size=8192' }, }, }, role: this.buildRole, }) this.pipeline.addStage({ stageName: 'Source', actions: [this.sourceAction], }) this.pipeline.addStage({ stageName: 'Lint', actions: [ new codepipeline_actions.CodeBuildAction({ actionName: 'Lint', project: lintProject, input: this.sourceOutput, role: this.pipelineRole, }), ], }) new CfnOutput(stack, `${baseName}PipelineURL`, { value: `https://${stack.region}.console.aws.amazon.com/codepipeline/home?region=${stack.region}#/view/${this.pipeline.pipelineName}`, description: 'Pipeline URL', }) } }
缺失的必要配置
AWS CodePipeline不会自动向Bitbucket推送构建状态,需要额外配置状态同步机制,同时补充Bitbucket侧的权限设置:
1. 配置EventBridge+Lambda同步Pipeline状态到Bitbucket
Bitbucket的提交状态需要通过其API主动更新,你需要:
- 创建EventBridge规则,捕获CodePipeline的执行状态变化事件
- 编写Lambda函数,接收事件后调用Bitbucket API更新对应提交的状态
- 给Lambda配置必要的权限和环境变量
代码补充示例
在BasePipeline类的构造函数末尾添加以下代码:
// 1. 创建EventBridge规则,监听Pipeline执行状态变化 const pipelineStateRule = new events.Rule(stack, `${baseName}PipelineStateRule`, { eventPattern: { source: ['aws.codepipeline'], detailType: ['CodePipeline Pipeline Execution State Change'], detail: { pipeline: [this.pipeline.pipelineName], }, }, }); // 2. 创建Lambda函数,处理Bitbucket状态更新 const bitbucketStatusLambda = new lambda.Function(stack, `${baseName}BitbucketStatusLambda`, { runtime: lambda.Runtime.NODEJS_20_X, handler: 'index.handler', code: lambda.Code.fromInline(` const axios = require('axios'); exports.handler = async (event) => { const executionStatus = event.detail.state; const commitId = event.detail.executionTrigger?.commitId; const bitbucketToken = process.env.BITBUCKET_TOKEN; const repoOwner = process.env.BITBUCKET_OWNER; const repoName = process.env.BITBUCKET_REPO; const region = process.env.AWS_REGION; const pipelineName = event.detail.pipeline; if (!commitId || !bitbucketToken) return; // 映射AWS状态到Bitbucket状态值 const bitbucketState = { SUCCEEDED: 'SUCCESSFUL', FAILED: 'FAILED', STARTED: 'INPROGRESS', RESUMED: 'INPROGRESS', CANCELED: 'STOPPED' }[executionStatus] || 'INPROGRESS'; try { await axios.post( \`https://api.bitbucket.org/2.0/repositories/\${repoOwner}/\${repoName}/commit/\${commitId}/statuses/build\`, { state: bitbucketState, key: 'aws-codepipeline', name: 'AWS CodePipeline', url: \`https://\${region}.console.aws.amazon.com/codepipeline/home?region=\${region}#/view/\${pipelineName}\`, description: \`Pipeline执行状态:\${executionStatus}\`, }, { headers: { Authorization: \`Bearer \${bitbucketToken}\` }, } ); } catch (err) { console.error('更新Bitbucket状态失败:', err.response?.data || err.message); } }; `), environment: { BITBUCKET_TOKEN: '你的Bitbucket个人访问令牌', // 建议用AWS Secrets Manager存储,不要硬编码 BITBUCKET_OWNER: BITBUCKET_OWNER, BITBUCKET_REPO: BITBUCKET_REPO, AWS_REGION: stack.region, }, }); // 3. 给Lambda添加读取CodePipeline执行信息的权限 bitbucketStatusLambda.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['codepipeline:GetPipelineExecution'], resources: [this.pipeline.pipelineArn], })); // 4. 将Lambda设置为EventBridge规则的目标 pipelineStateRule.addTarget(new targets.LambdaFunction(bitbucketStatusLambda));
2. Bitbucket侧配置个人访问令牌(PAT)
在Bitbucket账户中创建一个PAT,需要勾选Repository > Write权限(用于更新提交状态),然后将该令牌安全存储(比如AWS Secrets Manager),再在Lambda的环境变量中引用。
3. 确认CodeStar Connection权限
在AWS控制台的CodeStar Connections中,确认连接已成功授权Bitbucket仓库,并且连接状态为"已连接"。
4. (可选)Pull Request状态同步
如果需要在Bitbucket PR中显示构建状态,需要确保:
- Pipeline的PR触发器配置正确(你的代码中已包含
pullRequests相关配置) - Lambda函数中处理PR相关的执行事件,从事件中提取PR对应的提交ID进行状态更新
内容的提问来源于stack exchange,提问作者PlayMa256
相关产品推荐
相关产品推荐

