diff --git a/.github/workflows/_app-path-filter.yaml b/.github/workflows/_app-path-filter.yaml new file mode 100644 index 000000000..dcbd4d59e --- /dev/null +++ b/.github/workflows/_app-path-filter.yaml @@ -0,0 +1,89 @@ +name: App Path Filter + +on: + workflow_call: + outputs: + apps: + description: "Indicates if there are changes in apps files folder" + value: ${{ jobs.app-path-filter.outputs.apps }} + charterafrica: + description: "Indicates if charterafrica app files have changed" + value: ${{ jobs.app-path-filter.outputs.charterafrica }} + civicsignalblog: + description: "Indicates if civicsignalblog app files have changed" + value: ${{ jobs.app-path-filter.outputs.civicsignalblog }} + climatemappedafrica: + description: "Indicates if climatemappedafrica app files have changed" + value: ${{ jobs.app-path-filter.outputs.climatemappedafrica }} + codeforafrica: + description: "Indicates if codeforafrica app files have changed" + value: ${{ jobs.app-path-filter.outputs.codeforafrica }} + pesayetu: + description: "Indicates if pesayetu app files have changed" + value: ${{ jobs.app-path-filter.outputs.pesayetu }} + roboshield: + description: "Indicates if roboshield app files have changed" + value: ${{ jobs.app-path-filter.outputs.roboshield }} + techlabblog: + description: "Indicates if techlabblog app files have changed" + value: ${{ jobs.app-path-filter.outputs.techlabblog }} + vpnmanager: + description: "Indicates if vpnmanager app files have changed" + value: ${{ jobs.app-path-filter.outputs.vpnmanager }} + +jobs: + app-path-filter: + name: App Path Filter + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + outputs: + apps: ${{ steps.path-filter.outputs.apps }} + charterafrica: ${{ steps.path-filter.outputs.charterafrica }} + civicsignalblog: ${{ steps.path-filter.outputs.civicsignalblog }} + climatemappedafrica: ${{ steps.path-filter.outputs.climatemappedafrica }} + codeforafrica: ${{ steps.path-filter.outputs.codeforafrica }} + pesayetu: ${{ steps.path-filter.outputs.pesayetu }} + roboshield: ${{ steps.path-filter.outputs.roboshield }} + techlabblog: ${{ steps.path-filter.outputs.techlabblog }} + vpnmanager: ${{ steps.path-filter.outputs.vpnmanager }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Filter paths + uses: dorny/paths-filter@v3 + id: path-filter + with: + filters: | + shared: &shared + - Dockerfile + - packages/** + apps: + - *shared + - "apps/**" + charterafrica: + - *shared + - "apps/charterafrica/**" + civicsignalblog: + - *shared + - "apps/civicsignalblog/**" + climatemappedafrica: + - *shared + - "apps/climatemappedafrica/**" + codeforafrica: + - *shared + - "apps/codeforafrica/**" + pesayetu: + - *shared + - "apps/pesayetu/**" + roboshield: + - *shared + - "apps/roboshield/**" + techlabblog: + - *shared + - "apps/techlabblog/**" + vpnmanager: + - *shared + - "apps/vpnmanager/**" diff --git a/.github/workflows/_app-version-check.yaml b/.github/workflows/_app-version-check.yaml new file mode 100644 index 000000000..8989328b7 --- /dev/null +++ b/.github/workflows/_app-version-check.yaml @@ -0,0 +1,47 @@ +name: App Version Check + +on: + workflow_call: + inputs: + file-name: + required: true + type: string + description: "App name as it appears in 'apps' folder" + outputs: + changed: + description: "Either 'true' or 'false', indicates whether the version has changed" + value: ${{ jobs.app-version-check.outputs.changed }} + version: + description: "If the version has changed, it shows the version number" + value: ${{ jobs.app-version-check.outputs.version }} + +jobs: + app-version-check: + name: App Version Check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + outputs: + changed: ${{ steps.version-check.outputs.changed }} + version: ${{ steps.version-check.outputs.version }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version-file: "package.json" + + - name: Check version + id: version-check + uses: EndBug/version-check@v2 + with: + # Whether to search in every commit's diff. + # This is useful if you often do change the version without saying it + # in the commit message. If you always include the semver of the new + # version in your commit message when you bump versions then you can + # omit this. + diff-search: true + file-name: "${{ inputs.file-name }}" diff --git a/.github/workflows/_cd-charterafrica.yaml b/.github/workflows/_cd-charterafrica.yaml new file mode 100644 index 000000000..3029b3158 --- /dev/null +++ b/.github/workflows/_cd-charterafrica.yaml @@ -0,0 +1,85 @@ +name: CD | charterafrica + +on: + workflow_call: + inputs: + NODE_ENV: + required: true + type: string + description: "development|production" + app_url: + required: true + type: string + description: "App final URL" + seo_disabled: + required: true + type: string + description: "false|true" + build_args: + required: false + type: string + description: "List of build-time variables" + tags: + required: true + type: string + description: "List of tags" + git_remote_url: + required: true + type: string + description: "The dokku app's git repository url in SSH format" + +jobs: + # This seem to be needed because GitHub doesn't support access `secrets` in a `with` clause + # when calling reusable workflows + # https://github.com/github/roadmap/issues/636 + secrets: + runs-on: ubuntu-latest + outputs: + MONGO_URL: ${{ steps.output-secrets.outputs.CHARTERAFRICA_MONGO_URL }} + NEXT_PUBLIC_APP_LOGO_URL: ${{ steps.output-secrets.outputs.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }} + NEXT_PUBLIC_APP_NAME: ${{ steps.output-secrets.outputs.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }} + NEXT_PUBLIC_GA_MEASUREMENT_ID: ${{ steps.output-secrets.outputs.CHARTERAFRICA_GA_MEASUREMENT_ID }} + NEXT_PUBLIC_SENTRY_DSN: ${{ steps.output-secrets.outputs.CHARTERAFRICA_SENTRY_DSN }} + PAYLOAD_SECRET: ${{ steps.output-secrets.outputs.CHARTERAFRICA_PAYLOAD_SECRET_KEY }} + SENTRY_PROJECT: ${{ steps.output-secrets.outputs.CODEFORAFRICA_SENTRY_PROJECT }} + steps: + - id: output-secrets + run: | + echo "CHARTERAFRICA_GA_MEASUREMENT_ID=${{ secrets.CHARTERAFRICA_GA_MEASUREMENT_ID }}" >> "$GITHUB_OUTPUT" + echo "CHARTERAFRICA_MONGO_URL=${{ secrets.CHARTERAFRICA_MONGO_URL }}" >> "$GITHUB_OUTPUT" + echo "CHARTERAFRICA_SENTRY_DSN=${{ secrets.CHARTERAFRICA_SENTRY_DSN }}" >> "$GITHUB_OUTPUT" + echo "NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }}" >> "$GITHUB_OUTPUT" + echo "NEXT_PUBLIC_CODEFORAFRICA_APP_NAME=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }}" >> "$GITHUB_OUTPUT" + echo "CHARTERAFRICA_PAYLOAD_SECRET_KEY=${{ secrets.CHARTERAFRICA_PAYLOAD_SECRET_KEY }}" >> "$GITHUB_OUTPUT" + echo "CHARTERAFRICA_SENTRY_PROJECT=${{ secrets.CHARTERAFRICA_SENTRY_PROJECT }}" >> "$GITHUB_OUTPUT" + + build-docker-image: + name: Build Docker Image + needs: + - secrets + uses: ./.github/workflows/build-docker-image.yml + with: + build_args: | + ${{ inputs.build_args }} + MONGO_URL=${{ needs.secrets.outputs.MONGO_URL }} + NEXT_PUBLIC_APP_URL=${{ inputs.app_url }} + NEXT_PUBLIC_GA_MEASUREMENT_ID=${{ needs.secrets.outputs.NEXT_PUBLIC_GA_MEASUREMENT_ID }} + NEXT_PUBLIC_SENTRY_DSN=${{ needs.secrets.outputs.NEXT_PUBLIC_SENTRY_DSN }} + NEXT_PUBLIC_SEO_DISABLED=${{ inputs.seo_disabled }} + NODE_ENV=${{ inputs.NODE_ENV }} + PAYLOAD_SECRET_KEY=${{ needs.secrets.outputs.PAYLOAD_SECRET }} + SENTRY_ENVIRONMENT=${{ inputs.NODE_ENV }} + SENTRY_ORG=${{ vars.SENTRY_ORG }} + SENTRY_PROJECT=${{ needs.secrets.outputs.SENTRY_PROJECT }} + tags: ${{ inputs.tags }} + target: charterafrica-runner + secrets: inherit + + push-to-dokku: + name: Push to Dokku + needs: [build-docker-image] + uses: ./.github/workflows/push-to-dokku.yml + with: + git_remote_url: ${{ inputs.git_remote_url }} + deploy_docker_image: ${{ inputs.tags }} + secrets: inherit diff --git a/.github/workflows/_cd-codeforafrica.yaml b/.github/workflows/_cd-codeforafrica.yaml new file mode 100644 index 000000000..dd76dd3fb --- /dev/null +++ b/.github/workflows/_cd-codeforafrica.yaml @@ -0,0 +1,80 @@ +name: CD | codeforafrica + +on: + workflow_call: + inputs: + app_url: + required: true + type: string + description: "App final URL" + NODE_ENV: + required: true + type: string + description: "development|production" + build_args: + required: false + type: string + description: "List of build-time variables" + tags: + required: true + type: string + description: "List of tags" + git_remote_url: + required: true + type: string + description: "The dokku app's git repository url in SSH format" + secrets: + CODEFORAFRICA_MONGODB_URL: + required: true + NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL: + required: false + +jobs: + # This seem to be needed because GitHub doesn't support access `secrets` in a `with` clause + # when calling reusable workflows + # https://github.com/github/roadmap/issues/636 + secrets: + runs-on: ubuntu-latest + outputs: + MONGODB_URL: ${{ steps.output-secrets.outputs.CODEFORAFRICA_MONGODB_URL }} + NEXT_PUBLIC_APP_LOGO_URL: ${{ steps.output-secrets.outputs.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }} + NEXT_PUBLIC_APP_NAME: ${{ steps.output-secrets.outputs.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }} + PAYLOAD_SECRET: ${{ steps.output-secrets.outputs.CODEFORAFRICA_PAYLOAD_SECRET }} + SENTRY_PROJECT: ${{ steps.output-secrets.outputs.CODEFORAFRICA_SENTRY_PROJECT }} + steps: + - id: output-secrets + run: | + echo "CODEFORAFRICA_MONGODB_URL=${{ secrets.CODEFORAFRICA_MONGODB_URL }}" >> "$GITHUB_OUTPUT" + echo "NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }}" >> "$GITHUB_OUTPUT" + echo "NEXT_PUBLIC_CODEFORAFRICA_APP_NAME=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }}" >> "$GITHUB_OUTPUT" + echo "CODEFORAFRICA_PAYLOAD_SECRET=${{ secrets.CODEFORAFRICA_PAYLOAD_SECRET }}" >> "$GITHUB_OUTPUT" + echo "CODEFORAFRICA_SENTRY_PROJECT=${{ secrets.CODEFORAFRICA_SENTRY_PROJECT }}" >> "$GITHUB_OUTPUT" + + build-docker-image: + name: Build Docker Image + needs: + - secrets + uses: ./.github/workflows/build-docker-image.yml + with: + build_args: | + ${{ inputs.build_args }} + MONGODB_URL=${{ needs.secrets.outputs.MONGODB_URL }} + NEXT_PUBLIC_APP_LOGO_URL=${{ needs.secrets.outputs.NEXT_PUBLIC_APP_LOGO_URL }} + NEXT_PUBLIC_APP_NAME=${{ needs.secrets.outputs.NEXT_PUBLIC_APP_NAME }} + NEXT_PUBLIC_APP_URL=${{ inputs.app_url }} + NODE_ENV=${{ inputs.NODE_ENV }} + PAYLOAD_SECRET=${{ needs.secrets.outputs.PAYLOAD_SECRET }} + SENTRY_ENVIRONMENT=${{ inputs.NODE_ENV }} + SENTRY_PROJECT=${{ needs.secrets.outputs.SENTRY_PROJECT }} + tags: ${{ inputs.tags }} + target: "codeforafrica-runner" + secrets: inherit + + push-to-dokku: + name: Push to Dokku + needs: [build-docker-image] + uses: ./.github/workflows/push-to-dokku.yml + with: + git_remote_url: ${{ inputs.git_remote_url }} + deploy_docker_image: ${{ inputs.tags }} + secrets: inherit diff --git a/.github/workflows/_cd-dev.yaml b/.github/workflows/_cd-dev.yaml new file mode 100644 index 000000000..4789f06b8 --- /dev/null +++ b/.github/workflows/_cd-dev.yaml @@ -0,0 +1,34 @@ +name: DEV | CD + +on: + workflow_call: + +jobs: + apps-path-filter: + name: + uses: ./.github/workflows/_app-path-filter.yaml + + cd-dev-charterafrica: + needs: + - apps-path-filter + if: ${{ needs.apps-path-filter.outputs.charterafrica == 'true' }} + uses: ./.github/workflows/_cd-charterafrica.yaml + with: + NODE_ENV: development + app_url: "https://charterafrica.dev.codeforafrica.org" + seo_disabled: true + tags: "codeforafrica/charterafrica-ui:${{ github.sha }}" + git_remote_url: "ssh://azureuser@ui-1.dev.codeforafrica.org/charterafrica-ui" + secrets: inherit + + cd-dev-codeforafrica: + needs: + - apps-path-filter + if: ${{ needs.apps-path-filter.outputs.codeforafrica == 'true' }} + uses: ./.github/workflows/_cd-codeforafrica.yaml + with: + NODE_ENV: "development" + app_url: "https://codeforafrica-ui.dev.codeforafrica.org" + tags: "codeforafrica/codeforafrica-ui:${{ github.sha }}" + git_remote_url: "ssh://azureuser@ui-1.dev.codeforafrica.org/codeofrafrica-ui" + secrets: inherit diff --git a/.github/workflows/_cd-prod.yaml b/.github/workflows/_cd-prod.yaml new file mode 100644 index 000000000..1bf38adc2 --- /dev/null +++ b/.github/workflows/_cd-prod.yaml @@ -0,0 +1,46 @@ +name: PROD | CD + +on: + workflow_call: + +jobs: + version-check-charterafrica: + name: Version Check | charterafrica + uses: ./.github/workflows/_app-version-check.yaml + with: + file-name: "./apps/charterafrica/package.json" + secrets: inherit + + version-check-codeforafrica: + name: Version Check | codeforafrica + uses: ./.github/workflows/_app-version-check.yaml + with: + file-name: "./apps/codeforafrica/package.json" + secrets: inherit + + prod-cd-charterafrica: + name: Deploy | charterafrica + needs: + - version-check-charterafrica + if: ${{ needs.version-check-charterafrica.outputs.changed == 'true' }} + uses: ./.github/workflows/_cd-charterafrica.yaml + with: + NODE_ENV: production + app_url: https://charter.africa + seo_disabled: false + tags: "codeforafrica/charterafrica-ui:${{ needs.version-check-charterafrica.outputs.version }}" + git_remote_url: ssh://dokku@ui-1.prod.codeforafrica.org/charterafrica-ui + secrets: inherit + + prod-cd-codeforafrica: + name: Deploy | charterafrica + needs: + - version-check-codeforafrica + if: ${{ needs.version-check-codeforafrica.outputs.changed == 'true' }} + uses: ./.github/workflows/_cd-codeforafrica.yaml + with: + NODE_ENV: production + app_url: https://cfa.dev.codeforafrica.org + tags: "codeforafrica/codeforafrica-ui:${{ needs.version-check-codeforafrica.outputs.version }}" + git_remote_url: ssh://dokku@ui-1.prod.codeforafrica.org/codeforafrica-ui + secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/_ci.yaml similarity index 52% rename from .github/workflows/ci.yml rename to .github/workflows/_ci.yaml index 36c99ab94..a165d9d6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/_ci.yaml @@ -1,74 +1,55 @@ -name: CI +name: Continuous Integration on: - push: - branches: ["main"] - pull_request: - types: [opened, synchronize] - -# This allows a subsequently queued workflow run to interrupt previous runs -concurrency: - group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" - cancel-in-progress: true + workflow_call: jobs: - build: - name: Build and Test - timeout-minutes: 15 + ci: + name: Format, Lint and Test runs-on: ${{ matrix.os }} - env: - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - MONGO_URL: ${{ secrets.MONGO_URL }} - PROMISE_TRACKER_SENTRY_DSN: ${{ secrets.PROMISE_TRACKER_SENTRY_DSN }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} strategy: matrix: - node-version: [20.16] os: [ubuntu-latest] steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v4 - with: - fetch-depth: 2 # https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time - - name: Install pnpm + - name: Setup PNPM [Install] uses: pnpm/action-setup@v4 id: pnpm-install with: run_install: false - - name: Get pnpm store directory - id: pnpm-cache + - name: Setup PNPM [Path] + id: pnpm-path shell: bash run: | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - name: Setup pnpm cache + - name: Setup PNPM [Cache] uses: actions/cache@v4 with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + path: ${{ steps.pnpm-path.outputs.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- # Looks like to use pnpm cache, setup-node must run after pnpm/action-setup # https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#caching-packages-data - - name: Install Node.js + - name: Setup node uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} cache: "pnpm" + node-version-file: "package.json" - - name: Confirm pnpm version + - name: Setup PNPM [Confirm] run: pnpm --version - - name: Install dependencies + - name: Setup dependencies run: pnpm install - - name: Install Playwright browsers + - name: Setup dependencies [Playwright browsers] run: npx playwright install --with-deps - name: Format @@ -77,7 +58,7 @@ jobs: - name: Lint run: pnpm lint-check - - name: Jest + - name: "Test [unit: Jest]" run: pnpm jest # PromiseTracker seems to build success but then "hang". @@ -85,5 +66,5 @@ jobs: - name: Build run: pnpm build --filter=promisetracker^... - - name: Playwright + - name: "Test [integration: Playwright]" run: pnpm playwright --filter=promisetracker^... diff --git a/.github/workflows/codeforafrica-deploy-review-app.yml b/.github/workflows/codeforafrica-deploy-review-app.yml index d4045028d..54eec759b 100644 --- a/.github/workflows/codeforafrica-deploy-review-app.yml +++ b/.github/workflows/codeforafrica-deploy-review-app.yml @@ -1,102 +1,102 @@ -name: Code for Africa | Deploy | REVIEW APP +# name: Code for Africa | Deploy | REVIEW APP -on: - pull_request: - paths: - - "apps/codeforafrica/**" - - "Dockerfile" - - ".github/workflows/codeforafrica-deploy-review-app.yml" - # By default, a workflow only runs when a pull_request event's activity - # type is opened, synchronize, or reopened. We need at least closed to - # be able to destroy preview app - types: [opened, reopened, closed, synchronize] -concurrency: - group: "${{ github.workflow }} @ ${{ github.ref }}" - cancel-in-progress: false +# on: +# pull_request: +# paths: +# - "apps/codeforafrica/**" +# - "Dockerfile" +# - ".github/workflows/codeforafrica-deploy-review-app.yml" +# # By default, a workflow only runs when a pull_request event's activity +# # type is opened, synchronize, or reopened. We need at least closed to +# # be able to destroy preview app +# types: [opened, reopened, closed, synchronize] +# concurrency: +# group: "${{ github.workflow }} @ ${{ github.ref }}" +# cancel-in-progress: false -env: - DOKKU_REMOTE_BRANCH: "master" - DOKKU_REMOTE_URL: "ssh://azureuser@ui-1.dev.codeforafrica.org" - IMAGE_NAME: "codeforafrica/codeforafrica-ui" - ORIGINAL_APP_NAME: "codeforafrica-ui" - NEXT_PUBLIC_APP_URL: "https://codeforafrica-ui-pr-${{github.event.pull_request.number}}.dev.codeforafrica.org" - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - APP_NAME: codeforafrica-ui-pr-${{ github.event.pull_request.number }} +# env: +# DOKKU_REMOTE_BRANCH: "master" +# DOKKU_REMOTE_URL: "ssh://azureuser@ui-1.dev.codeforafrica.org" +# IMAGE_NAME: "codeforafrica/codeforafrica-ui" +# ORIGINAL_APP_NAME: "codeforafrica-ui" +# NEXT_PUBLIC_APP_URL: "https://codeforafrica-ui-pr-${{github.event.pull_request.number}}.dev.codeforafrica.org" +# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} +# APP_NAME: codeforafrica-ui-pr-${{ github.event.pull_request.number }} -jobs: - deploy_review_app: - runs-on: ${{ matrix.os }} - strategy: - matrix: - node-version: [20.16] - os: [ubuntu-latest] - if: github.event_name == 'pull_request' && github.event.action != 'closed' - steps: - - name: Cloning repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 +# jobs: +# deploy_review_app: +# runs-on: ${{ matrix.os }} +# strategy: +# matrix: +# node-version: [20.16] +# os: [ubuntu-latest] +# if: github.event_name == 'pull_request' && github.event.action != 'closed' +# steps: +# - name: Cloning repo +# uses: actions/checkout@v4 +# with: +# fetch-depth: 0 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 +# - name: Set up Docker Buildx +# uses: docker/setup-buildx-action@v3 - - name: Cache Docker layers - uses: actions/cache@v4 - with: - key: ${{ runner.os }}-buildx-${{ github.sha }} - path: /tmp/.buildx-cache - restore-keys: | - ${{ runner.os }}-buildx- +# - name: Cache Docker layers +# uses: actions/cache@v4 +# with: +# key: ${{ runner.os }}-buildx-${{ github.sha }} +# path: /tmp/.buildx-cache +# restore-keys: | +# ${{ runner.os }}-buildx- - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - username: ${{ secrets.DOCKER_HUB_USERNAME }} +# - name: Login to DockerHub +# uses: docker/login-action@v3 +# with: +# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} +# username: ${{ secrets.DOCKER_HUB_USERNAME }} - - name: Build Docker image - uses: docker/build-push-action@v5 - with: - build-args: | - MONGODB_URL=${{ secrets.CODEFORAFRICA_MONGO_URL }}/${{ env.APP_NAME }} - NEXT_PUBLIC_APP_LOGO_URL=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }} - NEXT_PUBLIC_APP_NAME=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }} - NEXT_PUBLIC_APP_URL=${{ env.NEXT_PUBLIC_APP_URL }} - PAYLOAD_SECRET=${{ secrets.CODEFORAFRICA_PAYLOAD_SECRET }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - context: . - target: codeforafrica-runner - push: true - tags: "${{ env.IMAGE_NAME }}:${{ github.sha }}" +# - name: Build Docker image +# uses: docker/build-push-action@v5 +# with: +# build-args: | +# MONGODB_URL=${{ secrets.CODEFORAFRICA_MONGO_URL }}/${{ env.APP_NAME }} +# NEXT_PUBLIC_APP_LOGO_URL=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_LOGO_URL }} +# NEXT_PUBLIC_APP_NAME=${{ secrets.NEXT_PUBLIC_CODEFORAFRICA_APP_NAME }} +# NEXT_PUBLIC_APP_URL=${{ env.NEXT_PUBLIC_APP_URL }} +# PAYLOAD_SECRET=${{ secrets.CODEFORAFRICA_PAYLOAD_SECRET }} +# cache-from: type=local,src=/tmp/.buildx-cache +# cache-to: type=local,dest=/tmp/.buildx-cache-new +# context: . +# target: codeforafrica-runner +# push: true +# tags: "${{ env.IMAGE_NAME }}:${{ github.sha }}" - - name: Push to dokku - uses: dokku/github-action@master - with: - command: review-apps:create - git_remote_url: ${{ env.DOKKU_REMOTE_URL }}/codeforafrica-ui - review_app_name: ${{ env.APP_NAME }} - ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} - deploy_docker_image: ${{ env.IMAGE_NAME }}:${{ github.sha }} +# - name: Push to dokku +# uses: dokku/github-action@master +# with: +# command: review-apps:create +# git_remote_url: ${{ env.DOKKU_REMOTE_URL }}/codeforafrica-ui +# review_app_name: ${{ env.APP_NAME }} +# ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} +# deploy_docker_image: ${{ env.IMAGE_NAME }}:${{ github.sha }} - - name: Update Preview URL - run: (gh pr comment ${{ env.issue-number }} --edit-last --body='${{ env.body }}' || gh pr comment ${{ env.issue-number }} --body='${{ env.body }}') - env: - issue-number: ${{ github.event.pull_request.number }} - body: | - Latest updated Preview URL - | Name | Review | - |-------|--------| - | ${{ env.APP_NAME }} | [Visit](https://${{ env.APP_NAME }}.dev.codeforafrica.org) | +# - name: Update Preview URL +# run: (gh pr comment ${{ env.issue-number }} --edit-last --body='${{ env.body }}' || gh pr comment ${{ env.issue-number }} --body='${{ env.body }}') +# env: +# issue-number: ${{ github.event.pull_request.number }} +# body: | +# Latest updated Preview URL +# | Name | Review | +# |-------|--------| +# | ${{ env.APP_NAME }} | [Visit](https://${{ env.APP_NAME }}.dev.codeforafrica.org) | - destroy_review_app: - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' && github.event.action == 'closed' - steps: - - name: Destroy review app - uses: dokku/github-action@master - with: - command: review-apps:destroy - git_remote_url: ${{ env.DOKKU_REMOTE_URL }}/codeforafrica-ui - review_app_name: ${{ env.APP_NAME }} - ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} +# destroy_review_app: +# runs-on: ubuntu-latest +# if: github.event_name == 'pull_request' && github.event.action == 'closed' +# steps: +# - name: Destroy review app +# uses: dokku/github-action@master +# with: +# command: review-apps:destroy +# git_remote_url: ${{ env.DOKKU_REMOTE_URL }}/codeforafrica-ui +# review_app_name: ${{ env.APP_NAME }} +# ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/.github/workflows/dependabot_lint_format.yml b/.github/workflows/dependabot_lint_format.yml deleted file mode 100644 index ff7acaa15..000000000 --- a/.github/workflows/dependabot_lint_format.yml +++ /dev/null @@ -1,79 +0,0 @@ -# When dependabot bumps dependencies versions, a new pnpm-lock.yml file -# is generated. This file needs to be formatted -# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions - -name: Dependabot lint-format -on: pull_request - -permissions: - contents: write - -jobs: - dependabot: - runs-on: ${{ matrix.os }} - strategy: - matrix: - node-version: [20.16] - os: [ubuntu-latest] - if: ${{ github.actor == 'dependabot[bot]' }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - - # https://github.com/pnpm/action-setup#use-cache-to-reduce-installation-time - - name: Install pnpm - uses: pnpm/action-setup@v4 - id: pnpm-install - with: - run_install: false - - - name: Get pnpm store directory - id: pnpm-cache - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - - name: Setup pnpm cache - uses: actions/cache@v4 - with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - # Looks like to use pnpm cache, setup-node must run after pnpm/action-setup - # https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#caching-packages-data - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - - - name: Confirm pnpm version - run: pnpm --version - - - name: Install dependencies - run: pnpm install - - - name: Format pnpm-lock.yaml - run: pnpm prettier --write './pnpm-lock.yaml' - - - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Format & lint pnpm-lock.yaml - file_pattern: "./pnpm-lock.yaml" - - - name: "Run lint (If there are changes)" - if: steps.auto-commit-action.outputs.changes_detected == 'true' - run: pnpm lint-check - - - name: "Run test (If there are changes)" - if: steps.auto-commit-action.outputs.changes_detected == 'true' - run: pnpm test - - - name: "Run build (If there are changes)" - if: steps.auto-commit-action.outputs.changes_detected == 'true' - run: pnpm build --filter=promisetracker^... diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 000000000..fe4f7c8ce --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,41 @@ +name: CI/CD [Main] + +on: + push: + branches: + - main + paths: + - ".github/workflows/**" + - "Dockerfile" + - "apps/**" + - "packages/**" + +# This allows a subsequently queued workflow run to interrupt previous runs +concurrency: + group: "${{ github.workflow }} @ ${{ github.ref }}" + cancel-in-progress: true + +jobs: + ci: + name: CI + uses: ./.github/workflows/_ci.yaml + + apps-path-filter: + uses: ./.github/workflows/_app-path-filter.yaml + secrets: inherit + + cd-dev: + needs: + - ci + - apps-path-filter + if: ${{ needs.apps-path-filter.outputs.apps == 'true' }} + uses: ./.github/workflows/_cd-dev.yaml + secrets: inherit + + cd-prod: + needs: + - ci + - apps-path-filter + if: ${{ needs.apps-path-filter.outputs.apps == 'true' }} + uses: ./.github/workflows/_cd-prod.yaml + secrets: inherit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 000000000..043768625 --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,21 @@ +name: CI/CD [PR] + +on: + pull_request: + branches: # PRs to the following branches will trigger the workflow + - main + paths: + - ".github/workflows/**" + - "apps/**" + - "packages/**" + +# This allows a subsequently queued workflow run to interrupt previous runs +concurrency: + group: "${{ github.workflow }} @ ${{ github.ref }}" + cancel-in-progress: true + +jobs: + ci: + name: CI + uses: ./.github/workflows/_ci.yaml +# TODO: deploy Dokku preview apps here diff --git a/.github/workflows/push-to-dokku.yml b/.github/workflows/push-to-dokku.yml index 0e81a7cf1..e257ec20e 100644 --- a/.github/workflows/push-to-dokku.yml +++ b/.github/workflows/push-to-dokku.yml @@ -6,11 +6,11 @@ on: git_remote_url: required: true type: string - description: "The remote URL to push to" + description: "The dokku app's git repository url in SSH format" deploy_docker_image: required: true type: string - description: "The name of the image to push" + description: "A docker image to deploy via git:from-image" jobs: push: diff --git a/.github/workflows/vpnmanager-deploy-dev.yml b/.github/workflows/vpnmanager-deploy-dev.yml index a157f58d5..6f67a7b26 100644 --- a/.github/workflows/vpnmanager-deploy-dev.yml +++ b/.github/workflows/vpnmanager-deploy-dev.yml @@ -5,7 +5,7 @@ on: branches: [main] paths: - "apps/vpnmanager/**" - - "Dockerfile.vpnmanager" + - "Dockerfile" - ".github/workflows/vpnmanager-deploy-dev.yml" # This allows a subsequently queued workflow run to interrupt previous runs diff --git a/apps/charterafrica/README.md b/apps/charterafrica/README.md index 7afec94b6..a2e4602fa 100644 --- a/apps/charterafrica/README.md +++ b/apps/charterafrica/README.md @@ -1,6 +1,6 @@ # Charter Africa -This is the official code for https://charter.africa site +This is the official code for site ## Getting Started @@ -12,7 +12,7 @@ cp env.template .env.local and modify the `.env.local` file according to your needs. -#### Note +### Note The default `.env` file is for the publicly visible environment variables. **DO NOT** include any secrets in it. All secrets should go into `env.local`. diff --git a/apps/charterafrica/package.json b/apps/charterafrica/package.json index ef297b0ce..05646df36 100644 --- a/apps/charterafrica/package.json +++ b/apps/charterafrica/package.json @@ -1,6 +1,6 @@ { "name": "charterafrica", - "version": "0.1.33", + "version": "0.1.33+202410071657", "private": true, "author": "Code for Africa ", "description": "This is the official code for https://charter.africa site", diff --git a/apps/codeforafrica/README.md b/apps/codeforafrica/README.md index 0790cac81..8f065f21b 100644 --- a/apps/codeforafrica/README.md +++ b/apps/codeforafrica/README.md @@ -12,7 +12,7 @@ cp env.template .env.local and modify the `.env.local` file according to your needs. -#### Note +### Note The default `.env` file is for the 'Publicly' visible environment variables.