即使有经验的建筑商也会不时遇到他们以前从未见过的事物,这会给他们带来麻烦。我已经与CDK,CodePipeline,CodeBuild和Golang合作了几年,并且不需要构建一个私人的Golang模块。几周前,情况发生了变化,这使我震惊,因为我还需要将其包含在CodeBuild步骤中的代码上。本文是未来的文档和参考,因为我想与CodeBuild分享用于构建Golang私有模块的模式。
解决方案图
供参考,这是解决方案图,我将在整个文章中引用。对于基础架构,我将使用CDK与Typescript。
管道
让我们漫步在codepipeline上,该码头将负责从GitHub接收更改,然后运行构建和部署。
export class PipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const pipeline = new CodePipeline(this, "Pipeline", {
pipelineName: "SamplePipeline",
dockerEnabledForSynth: true,
synth: new CodeBuildStep("Synth", {
input: CodePipelineSource.gitHub(
"benbpyle/cdk-step-functions-local-testing",
"main",
{
authentication: SecretValue.secretsManager(
"sf-sample",
{
jsonField: "github",
}
),
}
),
buildEnvironment: {
buildImage: LinuxBuildImage.STANDARD_6_0,
environmentVariables: {
GITHUB_USERNAME: {
value: "benbpyle",
type: BuildEnvironmentVariableType.PLAINTEXT,
},
GITHUB_TOKEN: {
value: "sf-sample:github",
type: BuildEnvironmentVariableType.SECRETS_MANAGER,
},
},
},
partialBuildSpec: BuildSpec.fromObject({
phases: {
install: {
"runtime-versions": {
golang: "1.18",
},
},
},
}),
commands: [
'echo "machine github.com login $GITHUB_USERNAME password $GITHUB_TOKEN" >> ~/.netrc',
"npm i",
"export GOPRIVATE=github.com/benbpyle",
"npx cdk synth",
],
}),
});
pipeline.addStage(new PipelineAppStage(this, `Deploy`, {}));
}
}
我想分解其中的一些组件。
源动作
我正在使用GitHub源和SecretsManager来存储个人访问令牌,该令牌将处理更改并将源拉入代码构造步骤
input: CodePipelineSource.gitHub(
"benbpyle/cdk-step-functions-local-testing",
"main",
{
authentication: SecretValue.secretsManager(
"sf-sample",
{
jsonField: "github",
}
),
}
),
建立步骤
构建步骤还需要访问SecretsManager。我将在下面的commands
块中解释。构建环境使我能够设置构建图像,然后设置环境变量。通过使用SecretsManager,我可以将隐藏的访问令牌隐藏起来,但可以在构建中访问它。 CodeBuild在掩盖*****
的值中也做得很好,如果您尝试将其echo
算出来。
buildEnvironment: {
buildImage: LinuxBuildImage.STANDARD_6_0,
environmentVariables: {
GITHUB_USERNAME: {
value: "benbpyle",
type: BuildEnvironmentVariableType.PLAINTEXT,
},
GITHUB_TOKEN: {
value: "sf-sample:github",
type: BuildEnvironmentVariableType.SECRETS_MANAGER,
},
},
},
构建命令
这种模式的症结在于,我正在使用~/.netrc
文件存储我的github pat,以登录Golang从Github提出的命令时进行登录。有关~/.netrc
的更多信息,这是指向GNU的链接。并阅读Golang Modules的工作原理
commands: [
'echo "machine github.com login $GITHUB_USERNAME password $GITHUB_TOKEN" >> ~/.netrc',
"npm i",
"export GOPRIVATE=github.com/benbpyle",
"npx cdk synth",
],
当npx cdk synth
命令运行时,会发现堆栈中有一个Golang函数,并且将执行go mod tidy
,从而从依赖项中启动拉动。另一个关键部分是,我要设置$GOPRIVATE
环境变量,该变量告诉您不使用公共软件包注册表并从这些特定位置提取软件包。该变量可以是顶级路径,也可以是逗号分隔的列表。 An article描述了它在发行几个Golang版本时的用法。
部署
在此示例中,我已经部署了一个单个阶段,但是在生产用例中,您将拥有开发,测试,预生产,产品,产品等环境。
// The stage
export class PipelineAppStage extends cdk.Stage {
constructor(scope: Construct, id: string, props: cdk.StageProps) {
super(scope, id, props);
new MainStack(this, `App`, {});
}
}
// MainStack
export class MainStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
new ExampleFunc(this, "ExampleFunc");
}
}
// Function Definition
export class ExampleFunc extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
new GoFunction(scope, `ExampleFuncHandler`, {
entry: path.join(__dirname, `../../../src/example-func`),
functionName: `example-func`,
timeout: Duration.seconds(30),
bundling: {
goBuildFlags: ['-ldflags "-s -w"'],
},
});
}
}
在这里讨论不多,但是您可以看到:
的定义- appstage
- mainstack
- examplefunc
将所有内容融合在一起,将舞台添加到管道
pipeline.addStage(new PipelineAppStage(this, `Deploy`, {}));
用CodeBuild构建Golang私人模块
golang利用一个go.mod
文件和一个存储这些依赖关系的依赖项,版本和校验和的go.sum
文件。如果您的代码直接导入某些内容或您的代码导入具有该依赖关系,则您还列出了直接和间接的依赖关系。
此示例的go.mod
文件看起来像这样。
我对
有依赖性- 是的 as>
- Sirupsen(Logus)
- 我的个人私人图书馆
module example
go 1.18
require (
github.com/aws/aws-lambda-go v1.40.0
github.com/sirupsen/logrus v1.9.0
)
require (
github.com/benbpyle/golang-private-sample v0.0.0-20230506132255-dc7062e24dff
github.com/stretchr/testify v1.8.2
golang.org/x/sys v0.7.0
)
和处理程序代码引用了go.mod
文件中的那些东西,只是打印出消息
package main
import (
"context"
"github.com/aws/aws-lambda-go/lambda"
s "github.com/benbpyle/golang-private-sample"
"github.com/sirupsen/logrus"
)
func main() {
lambda.Start(handler)
}
func handler(ctx context.Context, event interface{}) error {
logrus.Info("Logging out the handler")
s.TestMe("the handler")
return nil
}
包起来
将所有这些放在一起将使您有能力在您的golang模块中拥有一定程度的隐私。当使用CodeBuild构建Golang Private模块时,您可以通过CDK,Terraform或本地云形式轻松地将其包含在管道中。如果您使用的是另一个CI/CD执行框架,则此方法也将起作用。
。与往常一样,本文的源代码可在GitHub上找到。随意克隆并尝试一下。但是请注意,您无法访问以下内容。
- 用您的私人存储库 替换我的私人存储库
-
sf-sample
秘密是我创建的,您需要创建自己的
享受快乐建筑!