Skip to content

Commit

Permalink
(feat) Start of CICD - pushing for test
Browse files Browse the repository at this point in the history
  • Loading branch information
rrw-zilliqa committed Oct 4, 2024
1 parent f0c8fc0 commit 7471f13
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 0 deletions.
137 changes: 137 additions & 0 deletions .github/workflows/cicd-stg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: "CICD staging"

on:
# Test run before merging
pull_request:
branches:
- main
# On merged
push:
branches:
- main
- users/richard/61-cicd

jobs:
build-makefile:
permissions:
id-token: write
contents: write
runs-on: ubuntu-22.04
# To test deployments, remove the github.ref_name clause: see devops/docs/z2-testing-apps.md - rrw 2024-04-12
# && github.ref_name == 'main'
if: github.actor != 'dependabot[bot]'
name: "Build image with Makefile"
strategy:
fail-fast: false
matrix:
application: [otterscan]
include:
- application: otterscan
image_name: otterscan
path: .
tag_length: 8
tag_latest: false
env:
DOCKER_DOMAIN: asia-docker.pkg.dev
REGISTRY: asia-docker.pkg.dev/prj-d-devops-services-4dgwlsse/zilliqa-public
steps:
- name: Checkout code
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
submodules: recursive
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0

- name: "Authenticate to Google Cloud - staging"
id: google-auth
uses: "google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa"
with:
token_format: "access_token"
workload_identity_provider: "${{ secrets.GCP_PRD_GITHUB_WIF }}"
service_account: "${{ secrets.GCP_STG_GITHUB_SA_DOCKER_REGISTRY }}"
create_credentials_file: true

- name: Login to the registry - staging
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20
with:
registry: ${{ env.DOCKER_DOMAIN }}
username: "oauth2accesstoken"
password: "${{ steps.google-auth.outputs.access_token }}"

- name: Get tag version - staging
id: set-tag
uses: Zilliqa/gh-actions-workflows/actions/generate-tag@v1
with:
tag: ${{ env.REGISTRY }}/${{ matrix.image_name }}
length: ${{ matrix.tag_length }}

- name: "Build and push ${{ matrix.application }} - staging"
env:
ENVIRONMENT: stg
IMAGE_TAG: ${{ steps.set-tag.outputs.tags }}
run: |
cd ${{ matrix.path }}
make image/build-and-push
- name: "Build and push ${{ matrix.application }} tag latest - staging"
if: ${{ matrix.tag_latest == true }}
env:
ENVIRONMENT: stg
IMAGE_TAG: "${{ env.REGISTRY }}/${{ matrix.image_name }}:latest"
run: |
cd ${{ matrix.path }}
make image/build-and-push
deploy-to-staging:
needs: [build-makefile]
permissions:
id-token: write
contents: write
runs-on: ubuntu-22.04
if: github.actor != 'dependabot[bot]' && github.ref_name == 'main'
strategy:
fail-fast: false
matrix:
application:
- developer-portal
env:
APP_NAME: ${{ matrix.application }}
Z_ENV: infra/live/gcp/non-production/prj-d-staging/z_ase1.yaml
Z_SERVICE_ACCOUNT: ${{ secrets.GCP_STG_GITHUB_SA_K8S_DEPLOY }}
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_STG }}
GITHUB_PAT: ${{ secrets.GH_PAT }}
Z_IMAGE: asia-docker.pkg.dev/prj-d-devops-services-4dgwlsse/zilliqa-private/z:latest
REGISTRY: asia-docker.pkg.dev
steps:
- name: Checkout
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
repository: Zilliqa/devops
token: ${{ env.GITHUB_PAT }}
ref: main
sparse-checkout: |
${{ env.Z_ENV }}
- name: Authenticate to Google Cloud
id: google-auth
uses: google-github-actions/auth@71fee32a0bb7e97b4d33d548e7d957010649d8fa
with:
token_format: "access_token"
workload_identity_provider: "${{ secrets.GCP_PRD_GITHUB_WIF }}"
service_account: ${{ env.Z_SERVICE_ACCOUNT }}
create_credentials_file: true

- name: Deploy application
run: |
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://${{ env.REGISTRY }}
docker run --rm \
-e ZQ_USER='${{ env.Z_SERVICE_ACCOUNT }}' \
-e Z_ENV='/devops/${{ env.Z_ENV }}' \
-e OP_SERVICE_ACCOUNT_TOKEN='${{ env.OP_SERVICE_ACCOUNT_TOKEN }}' \
-e GITHUB_PAT='${{ env.GITHUB_PAT }}' \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE='/google/application_default_credentials.json' \
-v `pwd`:/devops \
-v ${{ steps.google-auth.outputs.credentials_file_path }}:/google/application_default_credentials.json \
--name z_container ${{ env.Z_IMAGE }} \
bash -c "gcloud config set account ${{ env.Z_SERVICE_ACCOUNT }} && z /app /devops app sync --cache-dir .cache ${{ env.APP_NAME }}"
85 changes: 85 additions & 0 deletions Dockerfile.zilliqa
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
FROM node:22.9.0-alpine3.19 AS builder
WORKDIR /otterscan-build
COPY --link ["package.json", "package-lock.json", "/otterscan-build/"]
RUN npm ci --fetch-timeout 6000000 --verbose
COPY --link ["run-nginx.sh", "tsconfig.json", "tsconfig.node.json", "postcss.config.js", "tailwind.config.js", "vite.config.ts", "index.html", "/otterscan-build/"]
COPY --link ["public", "/otterscan-build/public/"]
COPY --link ["src", "/otterscan-build/src/"]
COPY --link ["autogen", "/otterscan-build/autogen/"]
RUN npm run build-docker

# Add brotli module to official nginx image
# Based on: https://github.com/nginxinc/docker-nginx/tree/master/modules
FROM nginx:1.27.1-alpine3.20 as nginxbuilder

RUN set -ex \
&& apk update \
&& apk add linux-headers openssl-dev pcre-dev zlib-dev openssl abuild \
musl-dev libxslt libxml2-utils make mercurial gcc unzip git \
xz g++ coreutils \
# allow abuild as a root user \
&& printf "#!/bin/sh\\nSETFATTR=true /usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \
&& chmod +x /usr/local/bin/abuild \
&& hg clone -r ${NGINX_VERSION}-${PKG_RELEASE} https://hg.nginx.org/pkg-oss/ \
&& cd pkg-oss \
&& mkdir /tmp/packages \
&& for module in "brotli"; do \
echo "Building $module for nginx-$NGINX_VERSION"; \
if [ -d /modules/$module ]; then \
echo "Building $module from user-supplied sources"; \
# check if module sources file is there and not empty
if [ ! -s /modules/$module/source ]; then \
echo "No source file for $module in modules/$module/source, exiting"; \
exit 1; \
fi; \
# some modules require build dependencies
if [ -f /modules/$module/build-deps ]; then \
echo "Installing $module build dependencies"; \
apk update && apk add $(cat /modules/$module/build-deps | xargs); \
fi; \
# if a module has a build dependency that is not in a distro, provide a
# shell script to fetch/build/install those
# note that shared libraries produced as a result of this script will
# not be copied from the builder image to the main one so build static
if [ -x /modules/$module/prebuild ]; then \
echo "Running prebuild script for $module"; \
/modules/$module/prebuild; \
fi; \
/pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \
BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_\-\.\t ]')"; \
elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \
echo "Building $module from pkg-oss sources"; \
cd /pkg-oss/alpine; \
make abuild-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \
make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \
find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \
BUILT_MODULES="$BUILT_MODULES $module"; \
else \
echo "Don't know how to build $module module, exiting"; \
exit 1; \
fi; \
done \
&& echo "BUILT_MODULES=\"$BUILT_MODULES\"" > /tmp/packages/modules.env

FROM nginx:1.27.1-alpine3.20
COPY --from=nginxbuilder /tmp/packages /tmp/packages
RUN set -ex \
&& . /tmp/packages/modules.env \
&& for module in $BUILT_MODULES; do \
apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \
done \
&& rm -rf /tmp/packages
RUN apk update && apk add jq
WORKDIR /usr/share/nginx/html/
COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/chains chains/
COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/topic0 topic0/
COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/assets assets/
COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/signatures signatures/
COPY --link nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --link nginx/nginx.conf /etc/nginx/nginx.conf
COPY --link --from=builder /otterscan-build/dist /usr/share/nginx/html/
COPY --link --from=builder /otterscan-build/run-nginx.sh /
WORKDIR /

CMD ["/run-nginx.sh"]
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.PHONY: all
all: image/build-and-push

.ONESHELL:
SHELL := /bin/bash
.SHELLFLAGS = -ec

ENVIRONMENT ?= dev
VALID_ENVIRONMENTS := dev stg prd
# Check if the ENVIRONMENT variable is in the list of valid environments
ifeq ($(filter $(ENVIRONMENT),$(VALID_ENVIRONMENTS)),)
$(error Invalid value for ENVIRONMENT. Valid values are dev, stg, or prd.)
endif

HERE=$(shell pwd)

IMAGE_TAG ?= otterscan:latest


.PHONY: image/build-and-push
image/build-and-push:
./scripts/gen-version.sh autogen/version.ts
docker buildx build -f Dockerfile.zilliqa . -t $(IMAGE_TAG)
docker push "$(IMAGE_TAG)"
11 changes: 11 additions & 0 deletions cd/base/backend-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: otterscan
namespace: otterscan
labels:
app.kubernetes.io/name: "otterscan"
spec:
timeoutSec: 120
healthCheck:
requestPath: /health
33 changes: 33 additions & 0 deletions cd/base/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: otterscan
namespace: otterscan
labels:
app.kubernetes.io/name: "otterscan"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: "otterscan"
strategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: "otterscan"
spec:
containers:
- image: otterscan
name: otterscan
ports:
- containerPort: 80
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
readinessProbe:
httpGet:
path: /health
port: 80
11 changes: 11 additions & 0 deletions cd/base/frontend-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: developer-portal
namespace: developer-portal
labels:
app.kubernetes.io/name: "otterscan"
spec:
redirectToHttps:
enabled: true
responseCodeName: RESPONSE_CODE
21 changes: 21 additions & 0 deletions cd/base/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: otterscan
namespace: otterscan
labels:
app.kubernetes.io/name: "otterscan"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: localhost
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: otterscan
port:
number: 80
9 changes: 9 additions & 0 deletions cd/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- deployment.yaml
- svc.yaml
- ingress.yaml
- backend-config.yaml
- frontend-config.yaml
4 changes: 4 additions & 0 deletions cd/base/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: developer-portal
18 changes: 18 additions & 0 deletions cd/base/svc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: otterscan
namespace: otterscan
labels:
app.kubernetes.io/name: "otterscan"
annotations:
beta.cloud.google.com/backend-config: '{"default": "otterscan"}'
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app.kubernetes.io/name: "otterscan"
7 changes: 7 additions & 0 deletions cd/overlays/dev/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: developer-portal
spec:
domains:
- developer-portal.zildev.dev
Loading

0 comments on commit 7471f13

Please sign in to comment.