because I got bored of customising my CV for every job
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(CVG-29): extract CI logic into reusable scripts

+87 -47
+4 -10
.github/workflows/deploy-client.yml
··· 27 27 - name: Install dependencies 28 28 run: pnpm install --frozen-lockfile 29 29 30 - - name: Build client 30 + - name: Build and deploy 31 31 env: 32 - VITE_SERVER_URL: https://cv-generator-api.riotbyte.com 33 - run: pnpm --filter @cv/client build 34 - 35 - - name: Deploy to Cloudflare Pages 36 - uses: cloudflare/wrangler-action@v3 37 - with: 38 - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} 39 - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 40 - command: pages deploy apps/client/dist --project-name=cv-generator 32 + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} 33 + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 34 + run: ./ci/deploy-client.sh
+5 -37
.github/workflows/release.yml
··· 5 5 tags: 6 6 - "*.*.*" 7 7 8 - env: 9 - REGISTRY: ghcr.io 10 - IMAGE_BASE: ghcr.io/riotbyte-com/cv-generator 11 - 12 8 jobs: 13 9 build-and-push: 14 10 runs-on: ubuntu-latest ··· 16 12 contents: read 17 13 packages: write 18 14 19 - strategy: 20 - matrix: 21 - include: 22 - - name: server 23 - dockerfile: .docker/server.Dockerfile 24 - - name: worker 25 - dockerfile: .docker/worker.Dockerfile 26 - 27 15 steps: 28 16 - uses: actions/checkout@v4 29 17 30 - - uses: docker/login-action@v3 31 - with: 32 - registry: ${{ env.REGISTRY }} 33 - username: ${{ github.actor }} 34 - password: ${{ secrets.GITHUB_TOKEN }} 35 - 36 - - uses: docker/metadata-action@v5 37 - id: meta 38 - with: 39 - images: ${{ env.IMAGE_BASE }}-${{ matrix.name }} 40 - tags: | 41 - type=semver,pattern={{version}} 42 - type=semver,pattern={{major}}.{{minor}} 43 - type=ref,event=tag 44 - 45 - - uses: docker/build-push-action@v6 46 - with: 47 - context: . 48 - file: ${{ matrix.dockerfile }} 49 - target: production 50 - push: true 51 - tags: ${{ steps.meta.outputs.tags }} 52 - labels: ${{ steps.meta.outputs.labels }} 53 - build-args: | 54 - GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} 18 + - name: Build and push images 19 + env: 20 + VERSION: ${{ github.ref_name }} 21 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 + run: ./ci/build-images.sh
+53
ci/build-images.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + # Builds and pushes server + worker Docker images to GHCR. 5 + # 6 + # Required env vars: 7 + # VERSION — semver tag (e.g. "1.2.3") 8 + # GITHUB_TOKEN — GHCR auth token (also used as build arg for npm auth) 9 + # REGISTRY — container registry (default: ghcr.io) 10 + # IMAGE_BASE — image name prefix (default: ghcr.io/riotbyte-com/cv-generator) 11 + 12 + REGISTRY="${REGISTRY:-ghcr.io}" 13 + IMAGE_BASE="${IMAGE_BASE:-${REGISTRY}/riotbyte-com/cv-generator}" 14 + 15 + : "${VERSION:?VERSION is required}" 16 + : "${GITHUB_TOKEN:?GITHUB_TOKEN is required}" 17 + 18 + echo "${GITHUB_TOKEN}" | docker login "${REGISTRY}" -u _ --password-stdin 19 + 20 + IFS='.' read -r MAJOR MINOR PATCH <<< "${VERSION}" 21 + 22 + build_and_push() { 23 + local name="$1" 24 + local dockerfile="$2" 25 + local image="${IMAGE_BASE}-${name}" 26 + 27 + local tags=( 28 + "${image}:${VERSION}" 29 + "${image}:${MAJOR}.${MINOR}" 30 + "${image}:latest" 31 + ) 32 + 33 + local tag_args=() 34 + for t in "${tags[@]}"; do 35 + tag_args+=("-t" "$t") 36 + done 37 + 38 + echo "Building ${image}:${VERSION} from ${dockerfile}..." 39 + docker build \ 40 + -f "${dockerfile}" \ 41 + --target production \ 42 + --build-arg "GITHUB_TOKEN=${GITHUB_TOKEN}" \ 43 + "${tag_args[@]}" \ 44 + . 45 + 46 + for t in "${tags[@]}"; do 47 + echo "Pushing ${t}..." 48 + docker push "$t" 49 + done 50 + } 51 + 52 + build_and_push server .docker/server.Dockerfile 53 + build_and_push worker .docker/worker.Dockerfile
+25
ci/deploy-client.sh
··· 1 + #!/usr/bin/env bash 2 + set -euo pipefail 3 + 4 + # Builds the client SPA and deploys to Cloudflare Pages. 5 + # 6 + # Required env vars: 7 + # CLOUDFLARE_API_TOKEN — Cloudflare API token with Pages permissions 8 + # CLOUDFLARE_ACCOUNT_ID — Cloudflare account ID 9 + # 10 + # Optional env vars: 11 + # VITE_SERVER_URL — API server URL (default: https://cv-generator-api.riotbyte.com) 12 + # PAGES_PROJECT — Cloudflare Pages project name (default: cv-generator) 13 + 14 + export VITE_SERVER_URL="${VITE_SERVER_URL:-https://cv-generator-api.riotbyte.com}" 15 + PAGES_PROJECT="${PAGES_PROJECT:-cv-generator}" 16 + 17 + : "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN is required}" 18 + : "${CLOUDFLARE_ACCOUNT_ID:?CLOUDFLARE_ACCOUNT_ID is required}" 19 + 20 + echo "Building client with VITE_SERVER_URL=${VITE_SERVER_URL}..." 21 + pnpm --filter @cv/client build 22 + 23 + echo "Deploying to Cloudflare Pages project '${PAGES_PROJECT}'..." 24 + npx wrangler pages deploy apps/client/dist \ 25 + --project-name="${PAGES_PROJECT}"