diff --git a/.github/actions/deploy/action.yml b/.github/actions/deploy/action.yml deleted file mode 100644 index dc5b05c7..00000000 --- a/.github/actions/deploy/action.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Deploy to Google Cloud -description: We are using it in preview-deploy, server, proxy, main workflows -inputs: - projectId: - required: true - description: Google Cloud project ID - region: - required: true - description: Server location - folder: - required: true - description: What project from monorepo deploy - registry: - required: true - description: Google Cloud Artifacts registry name - service: - required: true - description: Google Cloud Run service name - tag: - required: false - default: latest - description: Docker image tag - env: - required: false - description: Google Cloud Run environment - flags: - required: false - description: Extra flags for Google Cloud Run deploy command - shutdown: - required: false - description: Shutdown HTTP endpoint -outputs: - url: - value: ${{ steps.deploy.outputs.url }} - description: Deployed app URL -runs: - using: composite - steps: - - name: Build Docker image - shell: bash - run: docker build -t ${{ inputs.region }}-docker.pkg.dev/${{ inputs.projectId }}/${{ inputs.registry }}:${{ inputs.tag }} ${{ inputs.folder }} - - name: Auth Google Cloud - uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 - with: - workload_identity_provider: projects/300174498438/locations/global/workloadIdentityPools/github/providers/hplush - service_account: github-deploy@${{ inputs.projectId }}.iam.gserviceaccount.com - - name: Install Google Cloud - uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1 - - name: Auth Docker - shell: bash - run: gcloud auth configure-docker ${{ inputs.region }}-docker.pkg.dev --quiet - - name: Push Docker image - shell: bash - run: docker push ${{ inputs.region }}-docker.pkg.dev/${{ inputs.projectId }}/${{ inputs.registry }}:${{ inputs.tag }} - - name: Shutdown previous version - shell: bash - if: ${{ inputs.shutdown }} - run: curl -X POST ${{ inputs.shutdown }} - - name: Deploy to Cloud Run - id: deploy - uses: google-github-actions/deploy-cloudrun@2028e2d7d30a78c6910e0632e48dd561b064884d # v3.0.1 - with: - gcloud_component: beta - service: ${{ inputs.service }} - region: ${{ inputs.region }} - image: ${{ inputs.region }}-docker.pkg.dev/${{ inputs.projectId }}/${{ inputs.registry }}:${{ inputs.tag }} - tag: ${{ inputs.tag != 'latest' && inputs.tag || '' }} - no_traffic: ${{ inputs.tag != 'latest' }} - flags: | - --allow-unauthenticated - --set-env-vars="${{ inputs.env }}" - --service-account=github-deploy@${{ inputs.projectId }}.iam.gserviceaccount.com - ${{ inputs.flags }} - - name: Move traffic to new revision - if: ${{ inputs.tag == 'latest' }} - shell: bash - run: | - gcloud run services update-traffic ${{ inputs.service }} \ - --project ${{ inputs.projectId }} \ - --region ${{ inputs.region }} \ - --to-latest - - name: Delete previous images - shell: bash - run: | - untagged=$(gcloud artifacts docker images list ${{ inputs.region }}-docker.pkg.dev/${{ inputs.projectId }}/${{ inputs.registry }} --include-tags --format="get(version)" --filter="NOT tags:*") - for digest in $untagged; do - image=${{ inputs.region }}-docker.pkg.dev/${{ inputs.projectId }}/${{ inputs.registry }}@$digest - echo "Deleting unused image: $image" - gcloud artifacts docker images delete $image --quiet - done diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1c837439..fd100db2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -62,7 +62,7 @@ jobs: if: github.ref == 'refs/heads/main' permissions: contents: read - id-token: write + packages: write concurrency: group: staging-web runs-on: ubuntu-latest @@ -74,17 +74,10 @@ jobs: allowed-endpoints: > 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 api.github.com:443 - artifactregistry.googleapis.com:443 cgr.dev:443 - dl.google.com:443 - europe-west1-docker.pkg.dev:443 - europe-west1-run.googleapis.com:443 github.com:443 - iamcredentials.googleapis.com:443 raw.githubusercontent.com:443 - run.googleapis.com:443 - serviceusage.googleapis.com:443 - sts.googleapis.com:443 + ghcr.io:443 - name: Checkout the repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Download web assets from test step @@ -92,11 +85,13 @@ jobs: with: name: web-client-assets-${{ github.sha }} path: web/ - - name: Deploy to Google Cloud - uses: ./.github/actions/deploy + - name: Build Docker image + run: docker build -t ghcr.io/hplush/slowreader-web:dev ./web/ + - name: Login to GitHub Container Registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - projectId: slowreader-453400 - region: europe-west1 - folder: ./web/ - registry: staging/web - service: staging-web + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push Docker image + run: docker push ghcr.io/hplush/slowreader-web:dev diff --git a/.github/workflows/preview-clean.yml b/.github/workflows/preview-clean.yml index 684b77cb..7287d103 100644 --- a/.github/workflows/preview-clean.yml +++ b/.github/workflows/preview-clean.yml @@ -12,9 +12,6 @@ jobs: close: name: Close runs-on: ubuntu-latest - env: - PROJECT_ID: slowreader-453400 - REGION: europe-west1 steps: - name: Harden the runner uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 @@ -24,18 +21,10 @@ jobs: 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 api.github.com:443 apk.cgr.dev:443 - artifactregistry.googleapis.com:443 cgr.dev:443 - dl.google.com:443 - europe-west1-docker.pkg.dev:443 - europe-west1-run.googleapis.com:443 github.com:443 - iamcredentials.googleapis.com:443 nodejs.org:443 raw.githubusercontent.com:443 - run.googleapis.com:443 - serviceusage.googleapis.com:443 - sts.googleapis.com:443 - name: Download PR number from prepare step uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: diff --git a/.github/workflows/preview-deploy.yml b/.github/workflows/preview-deploy.yml index 769fb25b..4d177e64 100644 --- a/.github/workflows/preview-deploy.yml +++ b/.github/workflows/preview-deploy.yml @@ -25,18 +25,10 @@ jobs: 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 api.github.com:443 apk.cgr.dev:443 - artifactregistry.googleapis.com:443 cgr.dev:443 - dl.google.com:443 - europe-west1-docker.pkg.dev:443 - europe-west1-run.googleapis.com:443 github.com:443 - iamcredentials.googleapis.com:443 nodejs.org:443 raw.githubusercontent.com:443 - run.googleapis.com:443 - serviceusage.googleapis.com:443 - sts.googleapis.com:443 - name: Checkout the repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Download server from prepare step @@ -46,12 +38,19 @@ jobs: repository: ${{ github.repository_owner }}/${{ github.event.repository.name }} run-id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.PREVIEW_ARTIFACT_PAT }} - - name: Extract archive to restore symlinks - run: tar -xf server.tar - name: Extract PR number run: | PR_NUMBER=$(cat ./preview-id) echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV + - name: Check preview label + run: | + LABELS=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json labels --jq '.labels[].name') + if ! echo "$LABELS" | grep -qx 'preview'; then + echo "PR #$PR_NUMBER does not have 'preview' label, skipping deploy" + exit 1 + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Notify about new deployment uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1.5.0 id: status @@ -60,19 +59,16 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} ref: ${{ github.event.workflow_run.head_commit.id }} env: preview-${{ env.PR_NUMBER }} - - name: Deploy to Google Cloud - id: deploy - uses: ./.github/actions/deploy + - name: Load Docker image + run: docker load < image.tar + - name: Login to GitHub Container Registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - projectId: slowreader-453400 - region: europe-west1 - folder: ./server/ - registry: staging/server - service: staging-server - tag: preview-${{ env.PR_NUMBER }} - env: ASSETS=1,DATABASE_URL=memory://,PROXY_ORIGIN=^https:\/\/preview-\d+---staging-server-300174498438\.europe-west1\.run\.app$ - # flags: | - # --update-secrets DATABASE_URL=preview-db-url:latest + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push Docker image + run: docker push ghcr.io/hplush/slowreader-proxy:dev - name: Update deployment status uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1.5.0 if: always() diff --git a/.github/workflows/preview-prepare.yml b/.github/workflows/preview-prepare.yml index c7164800..eed4eab6 100644 --- a/.github/workflows/preview-prepare.yml +++ b/.github/workflows/preview-prepare.yml @@ -1,6 +1,10 @@ name: Start Preview Deployment on: pull_request: + types: + - labeled + - synchronize + - opened paths-ignore: - '**/*.md' - 'scripts/**' @@ -19,6 +23,7 @@ jobs: prepare: name: Prepare runs-on: ubuntu-latest + if: contains(github.event.pull_request.labels.*.name, 'preview') steps: - name: Harden the runner uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 @@ -42,10 +47,12 @@ jobs: STAGING: 1 - name: Build server run: cd server && node --run build + - name: Build Docker image + run: docker build -t ghcr.io/hplush/slowreader:preview-${{ github.event.pull_request.number }} ./server/ + - name: Export image to tar + run: docker save ghcr.io/hplush/slowreader:preview-${{ github.event.pull_request.number }} > ./image.tar - name: Save PR number run: echo "${{ github.event.pull_request.number }}" > ./preview-id - - name: Create archive to keep symlinks - run: tar -cf server.tar server/dist/ - name: Save server for deploy uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: @@ -53,8 +60,5 @@ jobs: retention-days: 1 include-hidden-files: true path: | - server/web/ - server/Dockerfile - server/.dockerignore preview-id - server.tar + image.tar diff --git a/.github/workflows/proxy.yml b/.github/workflows/proxy.yml index e15902c7..24d71b43 100644 --- a/.github/workflows/proxy.yml +++ b/.github/workflows/proxy.yml @@ -10,7 +10,6 @@ on: - 'pnpm-lock.yaml' - '.github/workflows/proxy.yml' - '.github/actions/init-node/action.yml' - - '.github/actions/deploy/action.yml' pull_request: paths: - 'proxy/*' @@ -19,7 +18,6 @@ on: - 'pnpm-lock.yaml' - '.github/workflows/proxy.yml' - '.github/actions/init-node/action.yml' - - '.github/actions/deploy/action.yml' jobs: test: name: Proxy Test @@ -94,7 +92,7 @@ jobs: if: github.ref == 'refs/heads/main' permissions: contents: read - id-token: write + packages: write concurrency: group: staging-proxy runs-on: ubuntu-latest @@ -107,18 +105,11 @@ jobs: 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 api.github.com:443 apk.cgr.dev:443 - artifactregistry.googleapis.com:443 cgr.dev:443 - dl.google.com:443 - europe-west1-docker.pkg.dev:443 - europe-west1-run.googleapis.com:443 github.com:443 - iamcredentials.googleapis.com:443 nodejs.org:443 raw.githubusercontent.com:443 - run.googleapis.com:443 - serviceusage.googleapis.com:443 - sts.googleapis.com:443 + ghcr.io:443 - name: Checkout the repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Download web assets from test step @@ -128,12 +119,13 @@ jobs: path: ./ - name: Extract archive to restore symlinks run: tar -xf proxy.tar - - name: Deploy to Google Cloud - uses: ./.github/actions/deploy + - name: Build Docker image + run: docker build -t ghcr.io/hplush/slowreader-proxy:dev ./proxy/ + - name: Login to GitHub Container Registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - projectId: slowreader-453400 - region: europe-west1 - folder: ./proxy/ - registry: staging/proxy - service: staging-proxy - env: STAGING=1,PROXY_ORIGIN=^https:\/\/dev\.slowreader\.app$ + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push Docker image + run: docker push ghcr.io/hplush/slowreader-proxy:dev diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index 663b0d52..dbbc12f9 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -10,7 +10,6 @@ on: - 'pnpm-lock.yaml' - '.github/workflows/server.yml' - '.github/actions/init-node/action.yml' - - '.github/actions/deploy/action.yml' pull_request: paths: - 'server/*' @@ -19,7 +18,6 @@ on: - 'pnpm-lock.yaml' - '.github/workflows/server.yml' - '.github/actions/init-node/action.yml' - - '.github/actions/deploy/action.yml' jobs: test: name: Server Test @@ -68,9 +66,11 @@ jobs: uses: ./.github/actions/init-node with: cache: false - install: -F server -F proxy -F api --prod + install: -F server -F proxy -F api -F web --prod + - name: Build web client + run: cd web && node --run build - name: Build server - run: cd server && node --run build:server + run: cd server && node --run build - name: Create archive to keep symlinks run: tar -cf server.tar server/dist/ - name: Upload server build @@ -88,7 +88,7 @@ jobs: if: github.ref == 'refs/heads/main' permissions: contents: read - id-token: write + packages: write concurrency: group: staging-server runs-on: ubuntu-latest @@ -100,20 +100,13 @@ jobs: 9236a389bd48b984df91adc1bc924620.r2.cloudflarestorage.com:443 api.github.com:443 apk.cgr.dev:443 - artifactregistry.googleapis.com:443 cgr.dev:443 dev-server.slowreader.app:443 - dl.google.com:443 - europe-west1-docker.pkg.dev:443 - europe-west1-run.googleapis.com:443 github.com:443 - iamcredentials.googleapis.com:443 nodejs.org:443 release-assets.githubusercontent.com:443 raw.githubusercontent.com:443 - run.googleapis.com:443 - serviceusage.googleapis.com:443 - sts.googleapis.com:443 + ghcr.io:443 - name: Checkout the repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Download server build from previous step @@ -125,21 +118,13 @@ jobs: run: tar -xf server.tar - name: Create empty assets run: mkdir server/web - - name: Deploy to Google Cloud - uses: ./.github/actions/deploy + - name: Build Docker image + run: docker build -t ghcr.io/hplush/slowreader:dev ./server/ + - name: Login to GitHub Container Registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - projectId: slowreader-453400 - region: europe-west1 - folder: ./server/ - registry: staging/server - service: staging-server - shutdown: 'https://dev-server.slowreader.app/dump' - env: ASSETS=,PROXY_ORIGIN=,DATABASE_URL=dump:/var/mnt/db/db.pglite,DEBUG=1 - # Persistent database was disable temporary to save money - # flags: | - # --vpc-connector db-connector - # --update-secrets DATABASE_URL=staging-db-url:latest - flags: | - --memory 1Gi - --add-volume name=db,type=cloud-storage,bucket=slowreader-staging-db,mount-options=uid=65532;gid=65532 - --add-volume-mount volume=db,mount-path=/var/mnt/db + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Push Docker image + run: docker push ghcr.io/hplush/slowreader:dev diff --git a/proxy/Dockerfile b/proxy/Dockerfile index 41bcf868..bfc2f838 100644 --- a/proxy/Dockerfile +++ b/proxy/Dockerfile @@ -1,5 +1,9 @@ FROM cgr.dev/chainguard/wolfi-base@sha256:b5f4a33fa2fee95dd79535e069bafd60f52085c5786677da5724414374c5194c AS base +LABEL org.opencontainers.image.source=https://github.com/hplush/slowreader +LABEL org.opencontainers.image.description="Proxy server of Slow Reader" +LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later + ENV NODE_VERSION=24.13.1 \ NODE_CHECKSUM=sha256:30215f90ea3cd04dfbc06e762c021393fa173a1d392974298bbc871a8e461089 diff --git a/server/Dockerfile b/server/Dockerfile index 2d2879e4..3c2dbee4 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,5 +1,9 @@ FROM cgr.dev/chainguard/wolfi-base@sha256:b5f4a33fa2fee95dd79535e069bafd60f52085c5786677da5724414374c5194c AS base +LABEL org.opencontainers.image.source=https://github.com/hplush/slowreader +LABEL org.opencontainers.image.description="Slow Reader" +LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later + ENV NODE_VERSION=24.13.1 \ NODE_CHECKSUM=sha256:30215f90ea3cd04dfbc06e762c021393fa173a1d392974298bbc871a8e461089 diff --git a/web/Dockerfile b/web/Dockerfile index ad0ec2d3..54b934cc 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,6 +1,8 @@ -# Web server to serve web client for staging and pull request previews - FROM cgr.dev/chainguard/nginx@sha256:61af3191d30e6213ee8cd024e057965649ed0d5555c7b62fac7f31c8919844b2 +LABEL org.opencontainers.image.source=https://github.com/hplush/slowreader +LABEL org.opencontainers.image.description="Web client assets of Slow Reader" +LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later + COPY ./nginx.conf.compiled /etc/nginx/nginx.conf COPY ./dist/ /var/www/