From 71245e5aaae9edbce86d2602081ab646b8622a35 Mon Sep 17 00:00:00 2001 From: peterdeme Date: Sat, 25 Nov 2023 09:41:03 +0100 Subject: [PATCH] Use Goreleaser, and publish arm64 Signed-off-by: peterdeme --- .github/workflows/build-binary.yml | 32 ----- .github/workflows/build.yml | 33 +++++ .github/workflows/deployment.yml | 33 +++++ .github/workflows/linting.yml | 6 +- .github/workflows/preprod-deployment.yml | 176 ----------------------- .github/workflows/prod-deployment.yml | 176 ----------------------- .github/workflows/prod-pr.yml | 28 ---- .github/workflows/publish/action.yml | 153 ++++++++++++++++++++ .github/workflows/security.yml | 8 +- .github/workflows/trivy.yml | 88 ++++++------ .github/workflows/unit-testing.yml | 6 +- .gitignore | 2 + .goreleaser.yaml | 20 +++ Dockerfile | 7 +- README.md | 27 +++- 15 files changed, 323 insertions(+), 472 deletions(-) delete mode 100644 .github/workflows/build-binary.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/deployment.yml delete mode 100644 .github/workflows/preprod-deployment.yml delete mode 100644 .github/workflows/prod-deployment.yml delete mode 100644 .github/workflows/prod-pr.yml create mode 100644 .github/workflows/publish/action.yml create mode 100644 .goreleaser.yaml diff --git a/.github/workflows/build-binary.yml b/.github/workflows/build-binary.yml deleted file mode 100644 index ecd713c..0000000 --- a/.github/workflows/build-binary.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Build Binary - -on: { push: { branches-ignore: [main, production] } } - -jobs: - preprod-agent-deployment: - name: Build and upload agent - runs-on: ubuntu-latest - container: golang:1.20 - - env: - BASE_NAME: spacelift-vcs-agent - BIN_DIR: build - - steps: - - name: Check out repository code - uses: actions/checkout@v4 - - - name: Mark source directory as safe. # This is some duct tape over the git version in the Go image complaining about this since one of the 1.19.x versions. Feel free to remove once it doesn't break the build anymore. See https://github.com/actions/runner/issues/2033 and https://github.com/actions/checkout/issues/760#issuecomment-1097797031 - run: git config --global --add safe.directory $GITHUB_WORKSPACE - - - name: parse short SHA - id: vars - run: | - echo ::set-output name=sha::$(git rev-parse --short=8 ${{ github.sha }}) - - - name: Build Spacelift VCS Agent - run: go build -a -tags netgo -ldflags "-s -w -extldflags '-static' -X main.VERSION=$SHORT_SHA -X main.BugsnagAPIKey=$BUGSNAG_API_KEY" -trimpath -o $BIN_DIR/$BASE_NAME ./cmd/spacelift-vcs-agent - env: - BUGSNAG_API_KEY: ${{ secrets.PREPROD_BUGSNAG_API_KEY }} - CGO_ENABLED: 0 - SHORT_SHA: ${{ steps.vars.outputs.sha }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..4fbaa81 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,33 @@ +name: Build Binary + +on: { push: { branches-ignore: [main, production] } } + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-binary: + name: ๐Ÿ‘ท Build binary + runs-on: ubuntu-latest + container: golang:1.20 + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Mark source directory as safe. + run: git config --global --add safe.directory $GITHUB_WORKSPACE + + - name: parse short SHA + id: vars + run: | + echo ::set-output name=sha::$(git rev-parse --short=8 ${{ github.sha }}) + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + version: latest + args: release --snapshot + env: + BUGSNAG_API_KEY: ${{ secrets.PREPROD_BUGSNAG_API_KEY }} diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml new file mode 100644 index 0000000..7a64dc8 --- /dev/null +++ b/.github/workflows/deployment.yml @@ -0,0 +1,33 @@ +name: Preprod deployment + +on: [push] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + deployment: + name: ๐Ÿš€ Build and publish VCS Agent + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + packages: write + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Publish binary & Docker image + uses: ./.github/workflows/publish + with: + aws_role_to_assume: ${{ startsWith(github.ref, 'refs/tags/v') && secrets.AWS_ROLE_TO_ASSUME || secrets.PREPROD_AWS_ROLE_TO_ASSUME }} + ecr_repository_url: ${{ startsWith(github.ref, 'refs/tags/v') && secrets.PUBLIC_VCS_AGENT_ECR_REPOSITORY_URL || secrets.PREPROD_PUBLIC_VCS_AGENT_ECR_REPOSITORY_URL }} + aws_bucket: ${{ startsWith(github.ref, 'refs/tags/v') && secrets.AWS_S3_BUCKET || secrets.PREPROD_AWS_S3_BUCKET }} + cloudfront_distribution: ${{ startsWith(github.ref, 'refs/tags/v') && secrets.DISTRIBUTION || secrets.PREPROD_DISTRIBUTION }} + bugsnag_api_key: ${{ startsWith(github.ref, 'refs/tags/v') && secrets.BUGSNAG_API_KEY || secrets.PREPROD_BUGSNAG_API_KEY }} + gpg_key_id: ${{ secrets.GPG_KEY_ID }} + gpg_base64_key: ${{ secrets.GPG_KEY_BASE64 }} + gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 2052c91..67325be 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -2,9 +2,13 @@ name: Linting on: { push: { branches-ignore: [main, production] } } +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: linting: - name: Lint the code + name: ๐Ÿค“ Lint the code runs-on: ubuntu-latest container: golang:1.20 diff --git a/.github/workflows/preprod-deployment.yml b/.github/workflows/preprod-deployment.yml deleted file mode 100644 index 97c8dd5..0000000 --- a/.github/workflows/preprod-deployment.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Preprod deployment - -on: - push: - branches: - - main - -jobs: - preprod-agent-deployment: - name: Build and upload agent - runs-on: ubuntu-latest - outputs: - deployment_id: ${{ steps.deployment.outputs.deployment_id }} - container: golang:1.20 - env: - BASE_NAME: spacelift-vcs-agent - BIN_DIR: build - permissions: - id-token: write - contents: read - deployments: write - - steps: - - name: Check out repository code - uses: actions/checkout@v4 - - - name: Mark source directory as safe. # This is some duct tape over the git version in the Go image complaining about this since one of the 1.19.x versions. Feel free to remove once it doesn't break the build anymore. See https://github.com/actions/runner/issues/2033 and https://github.com/actions/checkout/issues/760#issuecomment-1097797031 - run: git config --global --add safe.directory $GITHUB_WORKSPACE - - - uses: chrnorm/deployment-action@releases/v1 - name: Create GitHub deployment - if: ${{ github.ref == 'refs/heads/main' }} - id: deployment - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.dev/spacelift-vcs-agent - environment: preprod/vcs-agent - - - name: parse short SHA - id: vars - run: | - echo ::set-output name=sha::$(git rev-parse --short=8 ${{ github.sha }}) - - - name: Build Spacelift VCS Agent - run: go build -a -tags netgo -ldflags "-s -w -extldflags '-static' -X main.VERSION=$SHORT_SHA -X main.BugsnagAPIKey=$BUGSNAG_API_KEY" -trimpath -o $BIN_DIR/$BASE_NAME ./cmd/spacelift-vcs-agent - env: - BUGSNAG_API_KEY: ${{ secrets.PREPROD_BUGSNAG_API_KEY }} - CGO_ENABLED: 0 - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Install dependencies - run: | - apt-get update -y - apt-get install -y awscli zip - - - name: Import the PGP key - run: | - echo ${GPG_KEY_BASE64} | base64 -d > spacelift.gpg - gpg --import \ - --passphrase=$GPG_PASSPHRASE \ - --pinentry-mode=loopback \ - spacelift.gpg - rm spacelift.gpg - env: - GPG_KEY_BASE64: ${{ secrets.GPG_KEY_BASE64 }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - - name: Sign Spacelift VCS Agent Binary - run: ./scripts/sign.sh $BIN_DIR $BASE_NAME - env: - GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Verify Checksum Spacelift VCS Agent Binary - run: ./scripts/verify.sh $BIN_DIR $BASE_NAME - env: - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Upload the VCS Agent binary - uses: actions/upload-artifact@v3 - with: - name: vcs-agent-binary - path: build/ - retention-days: 1 - - - name: Update deployment status (failure) - uses: chrnorm/deployment-status@releases/v1 - if: failure() && ${{ github.ref == 'refs/heads/main' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.dev/spacelift-vcs-agent - state: "failure" - deployment_id: ${{ steps.deployment.outputs.deployment_id }} - - publish-preprod-agent-deployment: - name: Upload VCS agent binary and container image - needs: ["preprod-agent-deployment"] - runs-on: ubuntu-latest - - env: - BIN_DIR: build - permissions: - id-token: write - contents: read - deployments: write - - steps: - - name: Check out repository code - uses: actions/checkout@v4 - - - name: Download the VCS Agent binary - uses: actions/download-artifact@v3 - with: - name: vcs-agent-binary - path: ./build - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - if: ${{ github.ref == 'refs/heads/main' }} - with: - aws-region: eu-west-1 - role-to-assume: ${{ secrets.PREPROD_AWS_ROLE_TO_ASSUME }} - role-duration-seconds: 900 - - - name: Upload the VCS Agent binary to downloads.spacelift.dev - if: ${{ github.ref == 'refs/heads/main' }} - run: >- - aws s3 sync - ${BIN_DIR} s3://${{ secrets.PREPROD_AWS_S3_BUCKET }}/ - --no-progress - - - name: Invalidate downloads.spacelift.dev cache - if: ${{ github.ref == 'refs/heads/main' }} - run: >- - aws cloudfront create-invalidation - --distribution-id ${{ secrets.PREPROD_DISTRIBUTION }} - --paths "/*" - - - name: Log in to Amazon public ECR - if: ${{ github.ref == 'refs/heads/main' }} - run: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws - - # This will be needed in the future for adding multi architecture build support - # - name: Set up QEMU - # uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push the image - uses: docker/build-push-action@v5 - with: - context: . - platforms: linux/amd64 - push: ${{ github.ref == 'refs/heads/main' }} - tags: | - ${{ secrets.PREPROD_PUBLIC_VCS_AGENT_ECR_REPOSITORY_URL }}:latest - - - name: Update deployment status (success) - uses: chrnorm/deployment-status@releases/v1 - if: success() && ${{ github.ref == 'refs/heads/main' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.dev/spacelift-vcs-agent - state: "success" - deployment_id: ${{ needs.preprod-agent-deployment.outputs.deployment_id }} - - - name: Update deployment status (failure) - uses: chrnorm/deployment-status@releases/v1 - if: failure() && ${{ github.ref == 'refs/heads/main' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.dev/spacelift-vcs-agent - state: "failure" - deployment_id: ${{ needs.preprod-agent-deployment.outputs.deployment_id }} diff --git a/.github/workflows/prod-deployment.yml b/.github/workflows/prod-deployment.yml deleted file mode 100644 index 9d8b50a..0000000 --- a/.github/workflows/prod-deployment.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Prod deployment - -on: - push: - branches: - - production - -jobs: - prod-agent-deployment: - name: Build and upload agent - runs-on: ubuntu-latest - outputs: - deployment_id: ${{ steps.deployment.outputs.deployment_id }} - container: golang:1.20 - env: - BASE_NAME: spacelift-vcs-agent - BIN_DIR: build - permissions: - id-token: write - contents: read - deployments: write - - steps: - - name: Check out repository code - uses: actions/checkout@v4 - - - name: Mark source directory as safe. # This is some duct tape over the git version in the Go image complaining about this since one of the 1.19.x versions. Feel free to remove once it doesn't break the build anymore. See https://github.com/actions/runner/issues/2033 and https://github.com/actions/checkout/issues/760#issuecomment-1097797031 - run: git config --global --add safe.directory $GITHUB_WORKSPACE - - - uses: chrnorm/deployment-action@releases/v1 - name: Create GitHub deployment - if: ${{ github.ref == 'refs/heads/production' }} - id: deployment - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.io/spacelift-vcs-agent - environment: prod/vcs-agent - - - name: parse short SHA - id: vars - run: | - echo ::set-output name=sha::$(git rev-parse --short=8 ${{ github.sha }}) - - - name: Build Spacelift VCS Agent - run: go build -a -tags netgo -ldflags "-s -w -extldflags '-static' -X main.VERSION=$SHORT_SHA -X main.BugsnagAPIKey=$BUGSNAG_API_KEY" -trimpath -o $BIN_DIR/$BASE_NAME ./cmd/spacelift-vcs-agent - env: - BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} - CGO_ENABLED: 0 - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Install dependencies - run: | - apt-get update -y - apt-get install -y awscli zip - - - name: Import the PGP key - run: | - echo ${GPG_KEY_BASE64} | base64 -d > spacelift.gpg - gpg --import \ - --passphrase=$GPG_PASSPHRASE \ - --pinentry-mode=loopback \ - spacelift.gpg - rm spacelift.gpg - env: - GPG_KEY_BASE64: ${{ secrets.GPG_KEY_BASE64 }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - - name: Sign Spacelift VCS Agent Binary - run: ./scripts/sign.sh $BIN_DIR $BASE_NAME - env: - GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Verify Checksum Spacelift VCS Agent Binary - run: ./scripts/verify.sh $BIN_DIR $BASE_NAME - env: - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - - name: Upload the VCS Agent binary - uses: actions/upload-artifact@v3 - with: - name: vcs-agent-binary - path: build/ - retention-days: 1 - - - name: Update deployment status (failure) - uses: chrnorm/deployment-status@releases/v1 - if: failure() && ${{ github.ref == 'refs/heads/production' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.io/spacelift-vcs-agent - state: "failure" - deployment_id: ${{ steps.deployment.outputs.deployment_id }} - - publish-prod-agent-deployment: - name: Upload VCS agent binary and container image - needs: ["prod-agent-deployment"] - runs-on: ubuntu-latest - - env: - BIN_DIR: build - permissions: - id-token: write - contents: read - deployments: write - - steps: - - name: Check out repository code - uses: actions/checkout@v4 - - - name: Download the VCS Agent binary - uses: actions/download-artifact@v3 - with: - name: vcs-agent-binary - path: ./build - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 - if: ${{ github.ref == 'refs/heads/production' }} - with: - aws-region: eu-west-1 - role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} - role-duration-seconds: 900 - - - name: Upload the VCS Agent binary to downloads.spacelift.io - if: ${{ github.ref == 'refs/heads/production' }} - run: >- - aws s3 sync - ${BIN_DIR} s3://${{ secrets.AWS_S3_BUCKET }}/ - --no-progress - - - name: Invalidate downloads.spacelift.io cache - if: ${{ github.ref == 'refs/heads/production' }} - run: >- - aws cloudfront create-invalidation - --distribution-id ${{ secrets.DISTRIBUTION }} - --paths "/*" - - - name: Log in to Amazon public ECR - if: ${{ github.ref == 'refs/heads/production' }} - run: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws - - # This will be needed in the future for adding multi architecture build support - # - name: Set up QEMU - # uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push the image - uses: docker/build-push-action@v5 - with: - context: . - platforms: linux/amd64 - push: ${{ github.ref == 'refs/heads/production' }} - tags: | - ${{ secrets.PUBLIC_VCS_AGENT_ECR_REPOSITORY_URL }}:latest - - - name: Update deployment status (success) - uses: chrnorm/deployment-status@releases/v1 - if: success() && ${{ github.ref == 'refs/heads/production' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.io/spacelift-vcs-agent - state: "success" - deployment_id: ${{ needs.prod-agent-deployment.outputs.deployment_id }} - - - name: Update deployment status (failure) - uses: chrnorm/deployment-status@releases/v1 - if: failure() && ${{ github.ref == 'refs/heads/production' }} - with: - token: "${{ github.token }}" - target_url: https://downloads.spacelift.io/spacelift-vcs-agent - state: "failure" - deployment_id: ${{ needs.prod-agent-deployment.outputs.deployment_id }} diff --git a/.github/workflows/prod-pr.yml b/.github/workflows/prod-pr.yml deleted file mode 100644 index eab96da..0000000 --- a/.github/workflows/prod-pr.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: prod-pr - -on: - push: - branches: [main] - -jobs: - create-pr: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set PR template - id: template - uses: juliangruber/read-file-action@v1 - with: - path: .github/prod_deployment_template.md - trim: false - - - name: Create Pull Request - uses: vsoch/pull-request-action@1.0.24 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PASS_IF_EXISTS: true - PULL_REQUEST_BODY: ${{ steps.template.outputs.content }} - PULL_REQUEST_BRANCH: production - PULL_REQUEST_DRAFT: true - PULL_REQUEST_TITLE: Production deployment ๐ŸŽ diff --git a/.github/workflows/publish/action.yml b/.github/workflows/publish/action.yml new file mode 100644 index 0000000..89b95a7 --- /dev/null +++ b/.github/workflows/publish/action.yml @@ -0,0 +1,153 @@ +name: Publish VCS Agent +description: Builds and pushes the binaries to S3 and to the public ECR. + +inputs: + aws_role_to_assume: + description: The AWS role to assume. Used to authenticate with ECR. + required: true + ecr_repository_url: + description: The ECR repository URL. Used to push the Docker image. + required: true + aws_bucket: + description: The AWS bucket. Used to upload the binaries. + required: true + cloudfront_distribution: + description: The CloudFront distribution. Used to invalidate the cache. + required: true + bugsnag_api_key: + description: The Bugsnag API key. Used to authenticate with Bugsnag. + required: true + gpg_key_id: + description: The GPG key ID. Used to sign the binaries. + required: true + gpg_base64_key: + description: The GPG key. Used to sign the binaries. + required: true + gpg_passphrase: + description: The GPG passphrase. Used to sign the binaries. + required: true + github_token: + description: The GitHub token. Used to authenticate with GitHub. + required: true + +runs: + using: composite + steps: + - name: Setup Go + uses: actions/setup-go@v4 + with: { go-version: "1.20" } + + - name: test if gitub token is set + run: echo ${{ secrets.GITHUB_TOKEN }} + + - name: Fake tag for GoReleaser + if: ${{ !startsWith(github.ref, 'refs/tags/') }} + shell: bash + run: | + git config --local user.email "ci@spacelift.io" + git config --local user.name "GitHub Actions" + git tag -a -m "An noop tag to make GoReleaser happy" v0.0.0 + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + args: release --snapshot=${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') }} + env: + BUGSNAG_API_KEY: ${{ inputs.bugsnag_api_key }} + + - name: Import the PGP key + shell: bash + run: | + echo ${GPG_KEY_BASE64} | base64 -d > spacelift.gpg + gpg --import \ + --passphrase=$GPG_PASSPHRASE \ + --pinentry-mode=loopback \ + spacelift.gpg + rm spacelift.gpg + env: + GPG_KEY_BASE64: ${{ inputs.gpg_base64_key }} + GPG_PASSPHRASE: ${{ inputs.gpg_passphrase }} + + - name: Sign Spacelift VCS Agent Binary + shell: bash + run: | + chmod 755 ./dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent + ./scripts/sign.sh ./dist/vcs-agent_linux_amd64_v1 spacelift-vcs-agent + ./scripts/verify.sh ./dist/vcs-agent_linux_amd64_v1 spacelift-vcs-agent + + chmod 755 ./dist/vcs-agent_linux_arm64/spacelift-vcs-agent + ./scripts/sign.sh ./dist/vcs-agent_linux_arm64 spacelift-vcs-agent + ./scripts/verify.sh ./dist/vcs-agent_linux_arm64 spacelift-vcs-agent + env: + GPG_KEY_ID: ${{ inputs.gpg_key_id }} + GPG_PASSPHRASE: ${{ inputs.gpg_passphrase }} + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + with: + aws-region: eu-west-1 + role-to-assume: ${{ inputs.aws_role_to_assume }} + role-duration-seconds: 900 + + - name: Put the files into the right place + shell: bash + run: | + mkdir -p build + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent build/spacelift-vcs-agent + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent_SHA256SUMS build/spacelift-vcs-agent_SHA256SUMS + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent_SHA256SUMS.sig build/spacelift-vcs-agent_SHA256SUMS.sig + + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent build/spacelift-vcs-agent-x86_64 + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent_SHA256SUMS build/spacelift-vcs-agent-x86_64_SHA256SUMS + cp dist/vcs-agent_linux_amd64_v1/spacelift-vcs-agent_SHA256SUMS.sig build/spacelift-vcs-agent-x86_64_SHA256SUMS.sig + + cp dist/vcs-agent_linux_arm64/spacelift-vcs-agent build/spacelift-vcs-agent-aarch64 + cp dist/vcs-agent_linux_arm64/spacelift-vcs-agent_SHA256SUMS build/spacelift-vcs-agent-aarch64_SHA256SUMS + cp dist/vcs-agent_linux_arm64/spacelift-vcs-agent_SHA256SUMS.sig build/spacelift-vcs-agent-aarch64_SHA256SUMS.sig + + # For easier visibility, here's the list of files we're uploading: + ls -l build + + - name: Upload the VCS Agent binaries to downloads.spacelift.[dev|io] + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + shell: bash + run: >- + aws s3 sync + build/ s3://${{ inputs.aws_bucket }} + + - name: Invalidate downloads.spacelift.[dev|io] cache + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + shell: bash + run: >- + aws cloudfront create-invalidation + --distribution-id ${{ inputs.cloudfront_distribution }} + --paths "/*" + + - name: Log in to Amazon public ECR + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + shell: bash + run: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: { platforms: linux/amd64,linux/arm64 } + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + github-token: ${{ inputs.github_token }} + images: ${{ inputs.ecr_repository_url }} + + - name: Build and push the image + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 24b011d..60e7fc7 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -5,9 +5,13 @@ on: schedule: - cron: "19 7 * * 0" +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: codeql: - name: CodeQL + name: ๐Ÿ‘ฎโ€โ™€๏ธ CodeQL runs-on: ubuntu-latest steps: @@ -27,7 +31,7 @@ jobs: gosec: - name: GoSec + name: ๐Ÿ‘ฎโ€โ™€๏ธ GoSec runs-on: ubuntu-latest env: GO111MODULE: on diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 86e2439..2f5bca2 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -8,80 +8,76 @@ on: schedule: - cron: "19 7 * * 0" +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: - build: - name: Build + trivy: + name: ๐Ÿ” Trivy runs-on: ubuntu-latest - env: - BASE_NAME: spacelift-vcs-agent - BIN_DIR: build - steps: - name: Checkout uses: actions/checkout@v4 with: { fetch-depth: 0 } - - name: Set up Go + - name: Mark source directory as safe. + run: git config --global --add safe.directory $GITHUB_WORKSPACE + + - name: Setup Go uses: actions/setup-go@v4 - with: { go-version: 1.18 } + with: { go-version: "1.20" } - name: parse short SHA id: vars run: | echo ::set-output name=sha::$(git rev-parse --short=8 ${{ github.sha }}) - - name: Build Spacelift VCS Agent - run: go build -a -tags netgo -ldflags "-s -w -extldflags '-static' -X main.VERSION=$SHORT_SHA -X main.BugsnagAPIKey=$BUGSNAG_API_KEY" -trimpath -o $BIN_DIR/$BASE_NAME ./cmd/spacelift-vcs-agent + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + version: latest + args: release --snapshot env: BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} - CGO_ENABLED: 0 - SHORT_SHA: ${{ steps.vars.outputs.sha }} - - name: Archive artifacts for use in Docker build - uses: actions/upload-artifact@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 with: - name: build - path: | - build - - analyze: - name: Analyze with Trivy - needs: build - runs-on: ubuntu-latest + platforms: "linux/amd64,linux/arm64" - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Download build artifacts - uses: actions/download-artifact@v3 - with: - name: build - path: build - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - name: Build Docker image + run: | + docker build --platform linux/amd64 -t spacelift-vcs-agent:${{ github.sha }}-amd64 . + docker build --platform linux/arm64 -t spacelift-vcs-agent:${{ github.sha }}-arm64 . - - name: Build and push the image - uses: docker/build-push-action@v5 + - name: Run Trivy vulnerability scanner (amd64) + uses: aquasecurity/trivy-action@master with: - context: . - push: false - load: true - tags: "spacelift-vcs-agent:${{ github.sha }}" + image-ref: "spacelift-vcs-agent:${{ github.sha }}-amd64" + format: "template" + template: "@/contrib/sarif.tpl" + output: "trivy-results-amd64.sarif" + severity: "CRITICAL,HIGH" - - name: Run Trivy vulnerability scanner + - name: Run Trivy vulnerability scanner (arm64) uses: aquasecurity/trivy-action@master with: - image-ref: "spacelift-vcs-agent:${{ github.sha }}" + image-ref: "spacelift-vcs-agent:${{ github.sha }}-arm64" format: "template" template: "@/contrib/sarif.tpl" - output: "trivy-results.sarif" + output: "trivy-results-arm64.sarif" severity: "CRITICAL,HIGH" - - name: Upload Trivy scan results to GitHub Security tab + - name: Upload Trivy scan results to GitHub Security tab (amd64) + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: "trivy-results-amd64.sarif" + category: "Trivy (amd64)" + + - name: Upload Trivy scan results to GitHub Security tab (arm64) uses: github/codeql-action/upload-sarif@v2 with: - sarif_file: "trivy-results.sarif" - category: "Trivy" + sarif_file: "trivy-results-arm64.sarif" + category: "Trivy (arm64)" diff --git a/.github/workflows/unit-testing.yml b/.github/workflows/unit-testing.yml index c1905ba..c3fb72a 100644 --- a/.github/workflows/unit-testing.yml +++ b/.github/workflows/unit-testing.yml @@ -2,9 +2,13 @@ name: Unit testing on: { push: { branches-ignore: [main, production] } } +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: unit-testing: - name: Test the code + name: ๐Ÿงช Test the code runs-on: ubuntu-latest container: golang:1.20 diff --git a/.gitignore b/.gitignore index 723794d..f9e1b13 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ # Binary cmd/spacelift-vcs-agent/spacelift-vcs-agent + +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..e16e0d7 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,20 @@ +builds: + - main: ./cmd/spacelift-vcs-agent + binary: spacelift-vcs-agent + env: [CGO_ENABLED=0] + goos: [windows, linux, darwin] + goarch: [amd64, arm64] + flags: [-trimpath] + tags: [netgo] + ldflags: + - "-s -w -extldflags '-static' -X main.VERSION={{.ShortCommit}} -X main.BugsnagAPIKey={{.Env.BUGSNAG_API_KEY}}" + +changelog: + use: github-native + +archives: + - format: zip + name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + +release: + disable: true diff --git a/Dockerfile b/Dockerfile index 51df8c4..44f4e58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ FROM alpine:3.18 +ARG TARGETARCH RUN apk add --no-cache ca-certificates RUN apk upgrade --update-cache --available RUN adduser --disabled-password --no-create-home --uid=1983 spacelift -COPY build/spacelift-vcs-agent /usr/bin/spacelift-vcs-agent +COPY dist/vcs-agent_linux_${TARGETARCH}*/spacelift-vcs-agent /usr/bin/spacelift-vcs-agent RUN chmod +x /usr/bin/spacelift-vcs-agent -CMD ["/usr/bin/spacelift-vcs-agent", "serve"] +USER spacelift -USER spacelift \ No newline at end of file +CMD ["/usr/bin/spacelift-vcs-agent", "serve"] diff --git a/README.md b/README.md index 6053ec2..b5f3bb4 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,6 @@ that are not available via the public internet. For more information see . -## Running in vscode - -- Make a copy of the `.env.template` file and call it `.env` (see [here](#environment-variables) - for more information on how to configure your environment variables). -- Press F5 / run the _Launch Package_ configuration. - ## Environment Variables The VCS Agent requires the following environment variables to be configured to work: @@ -19,11 +13,13 @@ The VCS Agent requires the following environment variables to be configured to w | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | SPACELIFT_VCS_AGENT_POOL_TOKEN | The token downloaded from Spacelift when creating the pool. You can decode this from base64 to edit the VCS Gateway address. | | SPACELIFT_VCS_AGENT_TARGET_BASE_ENDPOINT | The base endpoint address for the VCS integration. For example `https://github.mycompany.com`. | -| SPACELIFT_VCS_AGENT_VENDOR | The VCS vendor to use. For example `bitbucket_datacenter` | +| SPACELIFT_VCS_AGENT_VENDOR | The VCS vendor to use. Possible values: `azure_devops`, `bitbucket_datacenter`, `github_enterprise` and `gitlab`. | In addition, when running locally, you may want to set `SPACELIFT_VCS_AGENT_DIAL_INSECURE=true` to enable the VCS Agent to communicate with a Gateway instance that isn't using TLS. +Run the `spacelift-vcs-agent --help` command to see all available options. + ### Running via Docker Use the following command to run the VCS Agent via Docker: @@ -36,3 +32,20 @@ docker run -it --rm -e "SPACELIFT_VCS_AGENT_POOL_TOKEN=" \ ``` To use this example, make sure to update the environment variables according to your environment as explained in the table above. + +### Development + +#### Running in VS Code + +- Make a copy of the `.env.template` file and call it `.env` (see [here](#environment-variables) + for more information on how to configure your environment variables). +- Press F5 / run the _Launch Package_ configuration. + +### Release (For Spacelift maintainers) + +Once you're ready to release a new version of the VCS Agent, bump a semver and push it: + +```shell +git tag -a -m "Release v1.0.0" v1.0.0 +git push origin v1.0.0 +```