From 13a12460028bda1f1d333e461d12fadb4789858d Mon Sep 17 00:00:00 2001 From: Naomi Kirby Date: Thu, 19 Sep 2024 12:41:24 -0700 Subject: [PATCH] AUT-105: Add GitHub deployment workflow (#330) * Attempt version generation * We don't really need to keep the sources in the final image * Update Makefile to generate version.json * Enable GCP login and artifact upload * Add version generation to integration tests too * Remove CircleCI deploy job * Make pushes dependent on environment variables. --- .circleci/config.yml | 49 +++--------------------- .github/workflows/deploy.yaml | 70 +++++++++++++++++++++++++++++++++++ .github/workflows/tests.yaml | 6 ++- .gitignore | 1 + Dockerfile | 15 ++++---- Makefile | 9 ++++- main.go | 1 + version.json | 1 - version.sh | 37 ++++++++++++++++++ 9 files changed, 134 insertions(+), 55 deletions(-) create mode 100644 .github/workflows/deploy.yaml delete mode 100644 version.json create mode 100755 version.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index bb00e5d..ed484d5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,6 +30,10 @@ jobs: - checkout - setup_remote_docker + - run: + name: Create a version.json + command: ./version.sh | tee version.json + - run: name: Install Autograph command: | @@ -59,14 +63,7 @@ jobs: - run: name: Create a version.json - command: | - # create a version.json per https://github.com/mozilla-services/Dockerflow/blob/master/docs/version_object.md - printf '{"commit":"%s","version":"%s","source":"https://github.com/%s/%s","build":"%s"}\n' \ - "$CIRCLE_SHA1" \ - "$CIRCLE_TAG" \ - "$CIRCLE_PROJECT_USERNAME" \ - "$CIRCLE_PROJECT_REPONAME" \ - "$CIRCLE_BUILD_URL" > version.json + command: ./version.sh | tee version.json - run: name: Build Docker image @@ -81,33 +78,6 @@ jobs: key: v1-{{ .Branch }}-{{epoch}} paths: - docker-cache/docker.tar - deploy: - docker: - - image: cimg/deploy:2024.03.1 - steps: - - setup_remote_docker - - restore_cache: - key: v1-{{.Branch}} - - run: - name: Restore Docker image cache - command: docker load -i docker-cache/docker.tar - - - run: - name: Deploy to Dockerhub - command: | - # deploy master - if [ "${CIRCLE_BRANCH}" == "main" ]; then - docker login -u $DOCKER_USER -p $DOCKER_PASS - docker tag app:build ${DOCKERHUB_REPO}:latest - docker push ${DOCKERHUB_REPO}:latest - elif [ ! -z "${CIRCLE_TAG}" ]; then - # deploy a release tag... - docker login -u $DOCKER_USER -p $DOCKER_PASS - echo "${DOCKERHUB_REPO}:${CIRCLE_TAG}" - docker tag app:build "${DOCKERHUB_REPO}:${CIRCLE_TAG}" - docker images - docker push "${DOCKERHUB_REPO}:${CIRCLE_TAG}" - fi workflows: version: 2 @@ -130,12 +100,3 @@ workflows: tags: only: /.*/ - - deploy: - requires: - - test - - build - filters: - tags: - only: /.*/ - branches: - only: main diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..658145f --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,70 @@ +name: Deploy +on: + workflow_dispatch: + push: + branches: + - main + tags: + - '[0-9]+.[0-9a-z]+.[0-9a-z]+' + +jobs: + docker: + name: Docker Images + runs-on: ubuntu-22.04 + environment: build + permissions: + contents: read + id-token: write + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker Metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ vars.DOCKERHUB_REPO }} + ${{ vars.GCP_PROJECT_ID && format('{0}-docker.pkg.dev/{1}/{2}/autograph-edge', vars.GAR_LOCATION, vars.GCP_PROJECT_ID, vars.GAR_REPOSITORY) }} + tags: | + type=semver,pattern={{raw}} + type=raw,value=latest,enable={{is_default_branch}} + + - id: gcp-auth + if: ${{ vars.GCP_PROJECT_ID }} + uses: google-github-actions/auth@v2 + with: + token_format: 'access_token' + service_account: artifact-writer@${{ vars.GCP_PROJECT_ID}}.iam.gserviceaccount.com + workload_identity_provider: ${{ vars.GCPV2_GITHUB_WORKLOAD_IDENTITY_PROVIDER }} + + - name: Login to Google Artifact Registry + if: ${{ vars.GCP_PROJECT_ID }} + uses: docker/login-action@v3 + with: + registry: ${{ vars.GAR_LOCATION }}-docker.pkg.dev + username: oauth2accesstoken + password: ${{ steps.gcp-auth.outputs.access_token }} + + - name: Login to Dockerhub + if: ${{ vars.DOCKERHUB_REPO }} + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Generate version.json + shell: bash + run: ./version.sh | tee version.json + + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: ${{ github.event_name != 'pull_request' }} + sbom: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + context: . diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 928931e..20d4c8a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -34,7 +34,11 @@ jobs: steps: - name: Clone repository uses: actions/checkout@v4 - + + - name: Generate version.json + shell: bash + run: ./version.sh | tee version.json + - name: Pull autograph image shell: bash run: docker pull mozilla/autograph diff --git a/.gitignore b/.gitignore index f70a965..38b08f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor/ +version.json coverage.out diff --git a/Dockerfile b/Dockerfile index f29e02a..ebbe52f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG GO_VERSION=1.22 #------------------------------------------------------------------------------ # Base Debian Image #------------------------------------------------------------------------------ -FROM debian:bookworm as base +FROM debian:bookworm AS base ARG GO_VERSION ENV DEBIAN_FRONTEND='noninteractive' \ @@ -20,6 +20,7 @@ RUN apt-get update && \ clang \ gcc \ libltdl-dev \ + git \ golang-${GO_VERSION} \ curl \ ca-certificates && \ @@ -31,13 +32,13 @@ RUN apt-get update && \ #------------------------------------------------------------------------------ # Build Stage #------------------------------------------------------------------------------ -FROM base as builder -ENV GO111MODULE on -ENV CGO_ENABLED 1 +FROM base AS builder +ENV GO111MODULE=on +ENV CGO_ENABLED=1 -ADD . /app/src/autograph +ADD . /app/src -RUN cd /app/src/autograph && go install . +RUN cd /app/src && go install . #------------------------------------------------------------------------------ # Deployment Stage @@ -46,7 +47,7 @@ FROM base EXPOSE 8080 # Copy compiled appliation from the builder. -ADD . /app/src/autograph +RUN mkdir /app ADD autograph-edge.yaml /app ADD version.json /app COPY --from=builder /go/bin/autograph-edge /usr/local/bin/autograph-edge diff --git a/Makefile b/Makefile index 69f52e9..42f86fa 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,12 @@ GO := GO111MODULE=on go all: lint vet test install -install: +version.json: + $(GO) generate + +install: version.json $(GO) install . -test: +test: version.json MOCK_AUTOGRAPH_CALLS=1 $(GO) test -v -count=1 -covermode=count -coverprofile=coverage.out . showcoverage: test $(GO) tool cover -html=coverage.out @@ -12,3 +15,5 @@ lint: golint *.go vet: $(GO) vet *.go + +.PHONY: all install test showcoverage lint vet diff --git a/main.go b/main.go index e886b72..29b2ebf 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,7 @@ type authorization struct { AddonCOSEAlgorithms []string } +//go:generate ./version.sh version.json //go:embed "version.json" var jsonVersion []byte diff --git a/version.json b/version.json deleted file mode 100644 index e9b9858..0000000 --- a/version.json +++ /dev/null @@ -1 +0,0 @@ -{"commit":"","version":"0.0.1","source":"https://github.com/mozilla-services/autograph-edge","build":""} diff --git a/version.sh b/version.sh new file mode 100755 index 0000000..a7d0d70 --- /dev/null +++ b/version.sh @@ -0,0 +1,37 @@ +#!/bin/bash +SRCDIR=$(dirname $0) + +if [ -n "$GITHUB_SHA" ]; then + # We are probably running in a Github workflow. + VERSION_SOURCE_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" + VERSION_COMMIT_HASH="$GITHUB_SHA" + VERSION_BUILD_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" + if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]; then + VERSION_TAG_NAME="$GITHUB_REF_NAME" + fi +elif [ -n "$CIRCLE_SHA1" ]; then + # We are running in a CircleCI job. + VERSION_SOURCE_URL="https://github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" + VERSION_COMMIT_HASH="$CIRCLE_SHA1" + VERSION_BUILD_URL="$CIRCLE_BUILD_URL" + VERSION_TAG_NAME="$CIRCLE_TAG" +elif [ -d ${SRCDIR}/.git ]; then + # Otherwise, try to grab version information from the git repository. + VERSION_COMMIT_HASH=$(git -C ${SRCDIR} rev-parse HEAD) + VERSION_SOURCE_URL=$(git -C ${SRCDIR} remote get-url origin) + VERSION_TAG_NAME=$(git -C ${SRCDIR} describe --tags --always) +fi + +# Redirect to a file if provided as an argument. +if [ $# -ge 1 ]; then + exec > $1 +fi + +cat << EOF +{ + "source": "${VERSION_SOURCE_URL}", + "commit": "${VERSION_COMMIT_HASH}", + "version: "${VERSION_TAG_NAME}", + "build: "${VERSION_BUILD_URL}", +} +EOF