From f8d454869aa6b67fefa88978e630c578c413e70d Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 29 Dec 2020 11:23:27 +0100 Subject: [PATCH 1/2] add pipelines --- .github/workflows/ci.yml | 41 +++++++++++ .github/workflows/prod.yml | 133 ++++++++++++++++++++++++++++++++++ .github/workflows/staging.yml | 95 ++++++++++++++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/prod.yml create mode 100644 .github/workflows/staging.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b2a9fd7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI + +on: + push: + branches-ignore: + - master + - staging + + pull_request: + +jobs: + docker-build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + + # setup docker actions https://github.com/docker/build-push-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build image + id: docker_build + uses: docker/build-push-action@v2 + with: + # https://github.com/docker/build-push-action/issues/220 + context: . + tags: wire/ci-test-image + push: false + + # Send webhook to Wire using Slack Bot + - name: Webhook to Wire + uses: 8398a7/action-slack@v2 + with: + status: ${{ job.status }} + author_name: Docker CI pipeline + env: + SLACK_WEBHOOK_URL: ${{ secrets.WEBHOOK_CI }} + # Send message only if previous step failed + if: failure() diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml new file mode 100644 index 0000000..341b985 --- /dev/null +++ b/.github/workflows/prod.yml @@ -0,0 +1,133 @@ +name: Release Pipeline + +on: + release: + types: published + +env: + # set docker image for the service - i.e. "wire-bot/poll" + DOCKER_IMAGE: wire-bot/aves + # name of the service in the Dagobah - the value for label name, i.e. "polls" + SERVICE_NAME: aves + +jobs: + deploy: + name: Deploy to production + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + + - name: Set Release Version + # use latest tag as release version + run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV + + # extract metadata for labels https://github.com/crazy-max/ghaction-docker-meta + - name: Docker meta + id: docker_meta + uses: crazy-max/ghaction-docker-meta@v1 + with: + images: eu.gcr.io/${{ env.DOCKER_IMAGE }} + + # setup docker actions https://github.com/docker/build-push-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + # login to GCR repo + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + registry: eu.gcr.io + username: _json_key + password: ${{ secrets.GCR_ACCESS_JSON }} + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + # push only if this is indeed a taged release + push: ${{ startsWith(github.ref, 'refs/tags/') }} + build-args: | + release_version=${{ env.RELEASE_VERSION }} + + # Checkout our Kubernetes configuration + - name: Checkout k8s deployment configuration + uses: actions/checkout@v2 + with: + repository: zinfra/dagobah + # TODO maybe change that to develop once we're in production + ref: master + path: deployment-configuration-repo + # private repo so use different git token + token: ${{ secrets.DEPLOYMENT_CONFIGURATION_GIT_TOKEN }} + + # Update version to the one that was just built + - name: Change version in the k8s deployment configuration + env: + IMAGE: ${{ env.DOCKER_IMAGE }} + SERVICE: ${{ env.SERVICE_NAME }} + VERSION: ${{ env.RELEASE_VERSION }} + run: | + # go to directory with configuration + cd "deployment-configuration-repo/prod/$SERVICE" + # escape literals for the sed and set output with GCR + export SED_PREPARED=$(echo $IMAGE | awk '{ gsub("/", "\\/", $1); print "eu.gcr.io\\/"$1 }') + # update final yaml + sed -i".bak" "s/image: $SED_PREPARED.*/image: $SED_PREPARED:$VERSION/g" "$SERVICE.yaml" + # delete bakup file + rm "$SERVICE.yaml.bak" + + # Setup gcloud CLI + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@master + with: + service_account_email: kubernetes-deployment-agent@wire-bot.iam.gserviceaccount.com + service_account_key: ${{ secrets.GKE_SA_KEY }} + project_id: wire-bot + export_default_credentials: true + + # Configure Docker to use the gcloud command-line tool + - name: Configure Docker Google cloud + run: | + gcloud --quiet auth configure-docker + + # Get the GKE credentials so we can deploy to the cluster + - name: Obtain k8s credentials + env: + GKE_CLUSTER: dagobah + GKE_ZONE: europe-west1-c + run: | + gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE" + + # K8s is set up, deploy the app + - name: Deploy the Service + env: + SERVICE: ${{ env.SERVICE_NAME }} + run: | + kubectl apply -f "deployment-configuration-repo/prod/$SERVICE/$SERVICE.yaml" + + # Commit all data to deployment repo and open PR + - name: Create k8s deployment configuration PR + uses: peter-evans/create-pull-request@v3 + with: + path: deployment-configuration-repo + branch: ${{ env.SERVICE_NAME }}-release + token: ${{ secrets.DEPLOYMENT_CONFIGURATION_GIT_TOKEN }} + labels: version-bump, automerge + title: ${{ env.SERVICE_NAME }} release ${{ env.RELEASE_VERSION }} + commit-message: ${{ env.SERVICE_NAME }} version bump to ${{ env.RELEASE_VERSION }} + body: | + This is automatic version bump from the pipeline. + + # Send webhook to Wire using Slack Bot + - name: Webhook to Wire + uses: 8398a7/action-slack@v2 + with: + status: ${{ job.status }} + author_name: ${{ env.SERVICE_NAME }} release pipeline + env: + SLACK_WEBHOOK_URL: ${{ secrets.WEBHOOK_RELEASE }} + # Notify every release + if: always() diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml new file mode 100644 index 0000000..f33a16a --- /dev/null +++ b/.github/workflows/staging.yml @@ -0,0 +1,95 @@ +name: Staging Deployment + +on: + push: + branches: + - staging + +env: + # set docker image for the service - i.e. "wire-bot/poll" + DOCKER_IMAGE: wire-bot/aves + # name of the service in the Dagobah - the value for label name, i.e. "polls" + SERVICE_NAME: aves + +jobs: + publish: + name: Deploy to staging + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + + # use latest tag as release version in the docker container + - name: Set Release Version + run: echo "RELEASE_VERSION=${GITHUB_SHA}" >> $GITHUB_ENV + + # extract metadata for labels https://github.com/crazy-max/ghaction-docker-meta + - name: Docker meta + id: docker_meta + uses: crazy-max/ghaction-docker-meta@v1 + with: + images: eu.gcr.io/${{ env.DOCKER_IMAGE }} + + # setup docker actions https://github.com/docker/build-push-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + # login to GCR repo + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + registry: eu.gcr.io + username: _json_key + password: ${{ secrets.GCR_ACCESS_JSON }} + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + push: true + build-args: | + release_version=${{ env.RELEASE_VERSION }} + + # Setup gcloud CLI + - name: Set up Cloud SDK + uses: google-github-actions/setup-gcloud@master + with: + service_account_email: kubernetes-deployment-agent@wire-bot.iam.gserviceaccount.com + service_account_key: ${{ secrets.GKE_SA_KEY }} + project_id: wire-bot + export_default_credentials: true + + # Configure Docker to use the gcloud command-line tool + - name: Configure Docker Google cloud + run: | + gcloud --quiet auth configure-docker + + # Get the GKE credentials so we can deploy to the cluster + - name: Obtain k8s credentials + env: + GKE_CLUSTER: dagobah + GKE_ZONE: europe-west1-c + run: | + gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE" + + # K8s is set up, deploy the app + - name: Deploy the Service + env: + SERVICE: ${{ env.SERVICE_NAME }} + run: | + kubectl delete pod -l app=$SERVICE -n staging + kubectl describe pod -l app=$SERVICE -n staging + + # Send webhook to Wire using Slack Bot + - name: Webhook to Wire + uses: 8398a7/action-slack@v2 + with: + status: ${{ job.status }} + author_name: ${{ env.SERVICE_NAME }} staging pipeline + env: + SLACK_WEBHOOK_URL: ${{ secrets.WEBHOOK_CI }} + # Send message only if previous step failed + if: always() + From 1b14a7f9da966f774ae46910e64e423d1556bbd8 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 29 Dec 2020 15:38:57 +0100 Subject: [PATCH 2/2] firebase sdk file needs to exist --- .github/workflows/ci.yml | 4 ++++ .github/workflows/prod.yml | 6 ++++++ .github/workflows/staging.yml | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2a9fd7..4c10826 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,10 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Create dummy firebase SDK + run: | + echo "{}" > firebase-sdk.json + # setup docker actions https://github.com/docker/build-push-action - name: Set up QEMU uses: docker/setup-qemu-action@v1 diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index 341b985..ce877f1 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -17,6 +17,12 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Create firebase SDK + env: + SDK_JSON: ${{ secrets.FIREBASE_SDK }} + run: | + echo "${SDK_JSON}" > firebase-sdk.json + - name: Set Release Version # use latest tag as release version run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index f33a16a..f4b7c2e 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -18,6 +18,12 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Create firebase SDK + env: + SDK_JSON: ${{ secrets.FIREBASE_SDK }} + run: | + echo "${SDK_JSON}" > firebase-sdk.json + # use latest tag as release version in the docker container - name: Set Release Version run: echo "RELEASE_VERSION=${GITHUB_SHA}" >> $GITHUB_ENV