From 5eb51b4959a311022b440b3070bd767d26e21bd9 Mon Sep 17 00:00:00 2001 From: Julien Mourer Date: Thu, 29 Aug 2024 12:20:55 +0200 Subject: [PATCH] Set up Github Actions (#140) Migrate the CI from Google Cloud Build to Github Actions: 1. adds a RBAC so we can make the permissions the CI has access to very tight 2. migrate to Artifacts Registry which allows for scoping projects (and thus tighter permissions) 3. we like Github Actions better in terms of developer experience :slightly_smiling_face: 4. unify the way code is deployed at @poki --- .build/Dockerfile.deployer | 7 ---- .build/cloudbuild.yaml | 25 ------------- .build/deploy.sh | 41 --------------------- .github/workflows/build.yaml | 71 ++++++++++++++++++++++++++++++++++++ .github/workflows/ci.yaml | 16 -------- manifest/deployment.yaml | 4 +- manifest/rbac.yaml | 62 +++++++++++++++++++++++++++++++ manifest/secrets.yaml | 5 ++- 8 files changed, 138 insertions(+), 93 deletions(-) delete mode 100644 .build/Dockerfile.deployer delete mode 100644 .build/cloudbuild.yaml delete mode 100755 .build/deploy.sh create mode 100644 .github/workflows/build.yaml delete mode 100644 .github/workflows/ci.yaml create mode 100644 manifest/rbac.yaml diff --git a/.build/Dockerfile.deployer b/.build/Dockerfile.deployer deleted file mode 100644 index 8b91f89..0000000 --- a/.build/Dockerfile.deployer +++ /dev/null @@ -1,7 +0,0 @@ -# google/cloud-sdk:378.0.0-alpine -FROM google/cloud-sdk@sha256:eb796485dda671767ba1f8516f47099ea585c798c634f80da780a1c378b6af19 -RUN apk add --no-cache ca-certificates curl openssl git openssh-client bash gettext -RUN curl -sL "https://dl.k8s.io/release/v1.27.3/bin/linux/amd64/kubectl" -o /usr/bin/kubectl && chmod +x /usr/bin/kubectl -RUN gcloud components install gke-gcloud-auth-plugin -ENV USE_GKE_GCLOUD_AUTH_PLUGIN=True -RUN curl -sL https://github.com/mozilla/sops/releases/download/v3.6.1/sops-v3.6.1.linux -o /usr/bin/sops && chmod +x /usr/bin/sops diff --git a/.build/cloudbuild.yaml b/.build/cloudbuild.yaml deleted file mode 100644 index e232abc..0000000 --- a/.build/cloudbuild.yaml +++ /dev/null @@ -1,25 +0,0 @@ -steps: -- name: 'gcr.io/cloud-builders/docker' - args: [ - 'build', - '-t', 'eu.gcr.io/$PROJECT_ID/netlib-deployer', - '-f', '.build/Dockerfile.deployer', - '.' - ] -- name: 'gcr.io/cloud-builders/docker' - args: ['push', 'eu.gcr.io/$PROJECT_ID/netlib-deployer'] - -- name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'eu.gcr.io/$PROJECT_ID/netlib:$COMMIT_SHA', '.'] -- name: 'gcr.io/cloud-builders/docker' - args: ['push', 'eu.gcr.io/$PROJECT_ID/netlib:$COMMIT_SHA'] - -- name: 'eu.gcr.io/$PROJECT_ID/netlib-deployer' - args: ['.build/deploy.sh'] - env: - - BUILD_ID=${BUILD_ID} - - PROJECT_ID=${PROJECT_ID} - - BRANCH_NAME=${BRANCH_NAME} - - COMMIT_SHA=${COMMIT_SHA} - - CLOUDSDK_COMPUTE_ZONE=europe-west4-a - - CLUSTER=production-eu-west-4 diff --git a/.build/deploy.sh b/.build/deploy.sh deleted file mode 100755 index 6dbe17a..0000000 --- a/.build/deploy.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -set -euo pipefail -IFS=$'\n\t' - -NAMESPACE=netlib - -if [[ "${BRANCH_NAME:-""}" != "main" ]]; then - exit 0 -fi - -if [[ "${PROJECT_ID:-""}" == "" ]]; then - echo "PROJECT_ID is not set" - exit 1 -fi - -if [[ "${CLOUDSDK_COMPUTE_ZONE:-""}" == "" ]]; then - echo "CLOUDSDK_COMPUTE_ZONE is not set" - exit 1 -fi - -if [[ "${CLUSTER:-""}" == "" ]]; then - echo "CLUSTER is not set" - exit 1 -fi - -if [[ "${COMMIT_SHA:-""}" == "" ]]; then - COMMIT_SHA=$(git rev-parse HEAD) - export COMMIT_SHA -fi - -gcloud container clusters get-credentials --project="$PROJECT_ID" --zone="$CLOUDSDK_COMPUTE_ZONE" "$CLUSTER" - -kubectl version - -echo "Applying secrets..." -sops --decrypt "manifest/secrets.yaml" | kubectl apply -n "$NAMESPACE" --validate -f - - -echo "Deploying..." -kubectl kustomize "manifest" | envsubst | kubectl apply -n "$NAMESPACE" --validate -f - - -echo "Done" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..7a21b4d --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,71 @@ +name: Build + +on: + pull_request: + push: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.22.3' + - run: yarn install --frozen-lockfile + - run: yarn lint + - run: yarn cucumber + env: + DOCKER_HOST: unix:///var/run/docker.sock + build: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: GCP auth + uses: google-github-actions/auth@v2 + with: + credentials_json: '${{ secrets.GCP_CREDENTIALS }}' + - name: 'Set up Cloud SDK' + uses: google-github-actions/setup-gcloud@v2 + - name: Configure docker for GCP + run: gcloud auth configure-docker europe-docker.pkg.dev + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: true + tags: europe-docker.pkg.dev/${{ vars.GCP_PROJECT_ID }}/netlib/signaling:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + deploy: + runs-on: ubuntu-latest + needs: + - build + - test + timeout-minutes: 30 + if: github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + - name: GCP auth + uses: google-github-actions/auth@v2 + with: + credentials_json: '${{ secrets.GCP_CREDENTIALS }}' + - name: 'Set up Cloud SDK' + uses: google-github-actions/setup-gcloud@v2 + - uses: google-github-actions/get-gke-credentials@v2 + with: + cluster_name: production-eu-west-4 + location: europe-west4-a + - name: Install SOPS + run: |- + curl -LO https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 + chmod +x sops-v3.8.1.linux.amd64 + sudo mv sops-v3.8.1.linux.amd64 /usr/local/bin/sops + - name: Apply secrets + run: sops --decrypt "manifest/secrets.yaml" | kubectl apply --validate -f - + - name: Deploy + run: kubectl kustomize "manifest" | envsubst | kubectl apply --validate -f - diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index 6b34dee..0000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: CI -on: push -env: - DOCKER_HOST: unix:///var/run/docker.sock -jobs: - ci: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.22.3' - - run: go version - - run: yarn - - run: yarn lint - - run: yarn cucumber diff --git a/manifest/deployment.yaml b/manifest/deployment.yaml index 05df268..745d6e0 100644 --- a/manifest/deployment.yaml +++ b/manifest/deployment.yaml @@ -14,14 +14,14 @@ spec: spec: containers: - name: signaling - image: "eu.gcr.io/poki-core/netlib:$COMMIT_SHA" + image: "europe-docker.pkg.dev/poki-core/netlib/signaling:$GITHUB_SHA" ports: - containerPort: 8080 env: - name: ENV value: production - name: VERSION - value: "$COMMIT_SHA" + value: "$GITHUB_SHA" - name: DATABASE_URL valueFrom: secretKeyRef: diff --git a/manifest/rbac.yaml b/manifest/rbac.yaml new file mode 100644 index 0000000..6abc752 --- /dev/null +++ b/manifest/rbac.yaml @@ -0,0 +1,62 @@ +# this file needs permissions to be applied, which can be manually done with +# kubectl apply --validate -f manifest/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: netlib + name: netlib-ci +rules: +- apiGroups: [""] + resources: + - secrets + - services + verbs: + - get + - update + - create + - patch +- apiGroups: ["apps"] + resources: + - deployments + verbs: + - get + - update + - create + - patch +- apiGroups: ["networking.k8s.io"] + resources: + - ingresses + verbs: + - get + - update + - create + - patch +- apiGroups: ["cloud.google.com"] + resources: + - backendconfigs + verbs: + - get + - update + - create + - patch +- apiGroups: ["networking.gke.io"] + resources: + - managedCertificates + verbs: + - get + - update + - create + - patch +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: netlib-ci + namespace: netlib +subjects: +- kind: User + name: netlib-builder@poki-core.iam.gserviceaccount.com +roleRef: + kind: Role + name: netlib-ci + apiGroup: rbac.authorization.k8s.io diff --git a/manifest/secrets.yaml b/manifest/secrets.yaml index e032963..aa05df3 100644 --- a/manifest/secrets.yaml +++ b/manifest/secrets.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Secret metadata: name: netlib + namespace: netlib type: Opaque data: DATABASE_URL: ENC[AES256_GCM,data:EzXrkgS8BELub+ABWGD9PM+JoyRnsMkRBMFkeXSbgh+xRzn7/KZmXHwRnWXw5LWnoQfXQQ9wTySo5nqNRQNCDTdbqgsyT+X0aOnUfq5YngC858i1,iv:1Hu/EXqU77qxW0Et2N73OzO6e0AO/nIcTf/YKile07s=,tag:zA70VRtIQjuAN39Ce5CrpQ==,type:str] @@ -17,8 +18,8 @@ sops: azure_kv: [] hc_vault: [] age: [] - lastmodified: "2024-07-29T14:25:15Z" - mac: ENC[AES256_GCM,data:Tau418hZWnctbIN3XMLw/G86xb1+79cK0GkxdirjZGTlDvLloUdICdBUisJpaGeM8br2sVnfegbh6fc1FrXqD4a1VpL9Kwn78/hqWenKI9+Ll+fzbSTi9IxDTag4ajwhVaATsRD6UF3ue2ev0jmdlVIQYzPij2eXOhjSbasQt6g=,iv:mPiv7CBE6VvfQbuF8nWX6s+3UFUYbdQj+EDyjg8hx60=,tag:hpUZykrRD0n1jYL6+3f6AA==,type:str] + lastmodified: "2024-08-29T09:48:21Z" + mac: ENC[AES256_GCM,data:M2m0XS6hsH+NU5qiYqXpZhntUCGOCYrNxa4YSiNDEwZIJkjPBIEfbJ+ZaD9mqEvxpk7fC/MwYf4bS46IEJ6V4tHZwK8fKzvL2t52vfJiYkHLIKtKmRJLCxlYdbn/ruQPIvv/ESuF+myLo3LbbrokqdyhQVIgXexPah/7oYKaYAA=,iv:GLY3z5/GZhuyPenyIOjaHErAJx+8viLrwQRxVYjufUU=,tag:L+Yu3B5By6umHqLzVC5NcQ==,type:str] pgp: - created_at: "2024-03-26T10:58:44Z" enc: |-