Add conditional check to skip deployment if no image tags are available #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy to Staging | |
| on: | |
| push: | |
| branches: | |
| - "raymond/**" | |
| workflow_dispatch: | |
| inputs: | |
| name: | |
| description: "Manual workflow name" | |
| required: true | |
| permissions: | |
| id-token: write | |
| contents: write | |
| env: | |
| REGISTRY: gcr.io/linen-analyst-344721 | |
| DOCKER_REPOSITORY_OWNER: ${{ github.repository_owner }} | |
| GITOPS_REPO: speakeasy-api/gram-infra | |
| GITOPS_BRANCH: staging | |
| ENVIRONMENT: dev | |
| jobs: | |
| changes: | |
| name: Tag branch changes | |
| runs-on: ubicloud-standard-4 | |
| permissions: | |
| contents: "read" | |
| pull-requests: read | |
| outputs: | |
| server: ${{ steps.gates.outputs.server }} | |
| client: ${{ steps.gates.outputs.client }} | |
| steps: | |
| - name: Checkout source code | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
| name: Check for changed packages | |
| id: filter | |
| with: | |
| filters: .github/filters.yaml | |
| - id: gates | |
| name: Set outputs | |
| run: | | |
| if [[ "${{ steps.filter.outputs.server }}" == "true" || "${{ github.ref }}" == "refs/heads/main" ]]; then | |
| echo "server=true" >> $GITHUB_OUTPUT | |
| echo "Server jobs will run." | |
| else | |
| echo "Server jobs will be skipped." | |
| fi | |
| if [[ "${{ steps.filter.outputs.client }}" == "true" || "${{ github.ref }}" == "refs/heads/main" ]]; then | |
| echo "client=true" >> $GITHUB_OUTPUT | |
| echo "Client jobs will run." | |
| else | |
| echo "Client jobs will be skipped." | |
| fi | |
| build-and-deploy-dashboard: | |
| name: "Build and Deploy Dashboard" | |
| runs-on: ubicloud-standard-4 | |
| needs: changes | |
| outputs: | |
| dashboard-image-tag: ${{ steps.build-dashboard.outputs.image-tag }} | |
| env: | |
| GRAM_GIT_SHA: "${{ github.sha }}" | |
| steps: | |
| - name: Skip if no client changes exist | |
| if: ${{ needs.changes.outputs.client != 'true' }} | |
| run: echo "No client changes detected — skipping client-build-lint-test job." | |
| - name: Checkout | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| - name: Setup Mise | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| uses: jdx/mise-action@5ac50f778e26fac95da98d50503682459e86d566 # v3.2.0 | |
| with: | |
| install: true | |
| cache: true | |
| env: false | |
| - name: Prepare GitHub Actions environment | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| run: mise run github | |
| - name: Cache PNPM | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | |
| with: | |
| key: ${{ env.GH_CACHE_PNPM_KEY }} | |
| restore-keys: | | |
| ${{ env.GH_CACHE_PNPM_KEY }} | |
| ${{ env.GH_CACHE_PNPM_KEY_PARTIAL }} | |
| path: | | |
| ${{ env.PNPM_STORE_PATH }} | |
| - name: Install dependencies | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| run: pnpm install --frozen-lockfile | |
| - name: Build | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| env: | |
| NODE_ENV: production | |
| run: mise exec --env viteprod -- pnpm build | |
| - name: Upload source maps to DataDog | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| env: | |
| DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} | |
| run: mise run datadog:sourcemaps --git-sha "${{ github.sha }}" | |
| - name: Lint | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| run: pnpm lint | |
| working-directory: client/dashboard | |
| - name: Check for dirty files | |
| if: ${{ needs.changes.outputs.client == 'true' }} | |
| run: mise run git:porcelain | |
| - id: "auth" | |
| if: needs.changes.outputs.client == 'true' | |
| name: "Authenticate to Google Cloud" | |
| uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
| with: | |
| token_format: "access_token" | |
| workload_identity_provider: "projects/409661704476/locations/global/workloadIdentityPools/ga-pool/providers/github-oidc-provider" | |
| service_account: "speakeasy-registry-ga-ci@linen-analyst-344721.iam.gserviceaccount.com" | |
| - name: Login to GCR | |
| if: needs.changes.outputs.client == 'true' | |
| uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
| with: | |
| registry: gcr.io/linen-analyst-344721 | |
| username: oauth2accesstoken | |
| password: ${{ steps.auth.outputs.access_token }} | |
| - name: Build and Push Registry image to GCR | |
| id: build-dashboard | |
| if: needs.changes.outputs.client == 'true' | |
| uses: ./.github/workflows/composite/build-push | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: oauth2accesstoken | |
| password: ${{ steps.auth.outputs.access_token }} | |
| image: ${{ env.DOCKER_REPOSITORY_OWNER }}/gram-dashboard | |
| context: ./client/dashboard | |
| file: client/dashboard/Dockerfile | |
| git-auth-token: ${{ secrets.BOT_REPO_TOKEN }} | |
| - name: Prune PNPM store | |
| if: ${{ needs.changes.outputs.client == 'true' && success() }} | |
| run: pnpm store prune | |
| build-and-deploy-server: | |
| name: "Build and Deploy Server" | |
| runs-on: ubicloud-standard-4 | |
| needs: changes | |
| outputs: | |
| server-image-tag: ${{ steps.build-server.outputs.image-tag }} | |
| env: | |
| GOMAXPROCS: 4 | |
| steps: | |
| - name: Skip if no server changes exist | |
| if: ${{ needs.changes.outputs.server != 'true' }} | |
| run: echo "No server changes detected — skipping server-build-lint job." | |
| - name: Checkout | |
| if: ${{ needs.changes.outputs.server == 'true' }} | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| - id: "auth" | |
| if: ${{ needs.changes.outputs.server == 'true' }} | |
| name: "Authenticate to Google Cloud" | |
| uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 | |
| with: | |
| token_format: "access_token" | |
| workload_identity_provider: "projects/409661704476/locations/global/workloadIdentityPools/ga-pool/providers/github-oidc-provider" | |
| service_account: "speakeasy-registry-ga-ci@linen-analyst-344721.iam.gserviceaccount.com" | |
| - name: Login to GCR | |
| if: ${{ needs.changes.outputs.server == 'true' }} | |
| uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 | |
| with: | |
| registry: gcr.io/linen-analyst-344721 | |
| username: oauth2accesstoken | |
| password: ${{ steps.auth.outputs.access_token }} | |
| - name: Build and Push Registry image to GCR | |
| id: build-server | |
| if: ${{ needs.changes.outputs.server == 'true' }} | |
| uses: ./.github/workflows/composite/build-push | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: oauth2accesstoken | |
| password: ${{ steps.auth.outputs.access_token }} | |
| image: ${{ env.DOCKER_REPOSITORY_OWNER }}/gram | |
| context: ./server | |
| file: server/Dockerfile | |
| git-auth-token: ${{ secrets.BOT_REPO_TOKEN }} | |
| build-args: | | |
| GIT_USERNAME=speakeasybot | |
| - name: Pull and Run Image | |
| if: ${{ needs.changes.outputs.server == 'true' }} | |
| run: | | |
| echo "Pulling image: ${{ steps.build.outputs.image-tag }}" | |
| docker pull ${{ steps.build.outputs.image-tag }} | |
| echo "Running image..." | |
| docker run --rm ${{ steps.build.outputs.image-tag }} version | |
| update-gitops-and-deploy: | |
| runs-on: ubicloud-standard-4 | |
| needs: | |
| - build-and-deploy-server | |
| - build-and-deploy-dashboard | |
| steps: | |
| - name: Skip if no image tags are available | |
| run: | | |
| if [[ -z "${{ needs.build-and-deploy-server.outputs.server-image-tag }}" && -z "${{ needs.build-and-deploy-dashboard.outputs.dashboard-image-tag }}" ]]; then | |
| echo "No image tags available — skipping deployment." | |
| exit 0 | |
| fi | |
| echo "Image tags available, proceeding with deployment." | |
| - name: Checkout GitOps Repository | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 | |
| with: | |
| repository: ${{ env.GITOPS_REPO }} | |
| token: ${{ secrets.GITOPS_TOKEN }} | |
| path: gitops-repo | |
| ref: ${{ env.GITOPS_BRANCH }} | |
| - name: Setup GitOps Branch | |
| run: | | |
| cd gitops-repo | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| # Ensure we're on the staging branch and it's up to date | |
| git checkout ${{ env.GITOPS_BRANCH }} | |
| git pull origin ${{ env.GITOPS_BRANCH }} | |
| - name: Update Helm Values for Staging | |
| run: | | |
| # Update server image tag if available | |
| if [[ -n "${{ needs.build-and-deploy-server.outputs.server-image-tag }}" ]]; then | |
| echo "Updating server image tag to: ${{ needs.build-and-deploy-server.outputs.server-image-tag }}" | |
| yq eval ".image.tag = \"${{ needs.build-and-deploy-server.outputs.server-image-tag }}\"" \ | |
| -i gitops-repo/infra/helm/gram/values-dev.yaml | |
| fi | |
| # Update dashboard image tag if available | |
| if [[ -n "${{ needs.build-and-deploy-dashboard.outputs.dashboard-image-tag }}" ]]; then | |
| echo "Updating dashboard image tag to: ${{ needs.build-and-deploy-dashboard.outputs.dashboard-image-tag }}" | |
| if grep -q "dashboard:" gitops-repo/infra/helm/gram/values-dev.yaml; then | |
| yq eval ".dashboard.tag = \"${{ needs.build-and-deploy-dashboard.outputs.dashboard-image-tag }}\"" \ | |
| -i gitops-repo/infra/helm/gram/values-dev.yaml | |
| fi | |
| fi | |
| - name: Commit and Push Changes | |
| run: | | |
| cd gitops-repo | |
| git add . | |
| git commit -m "chore: update staging images to ${{ github.sha }}" | |
| git push origin ${{ env.GITOPS_BRANCH }} | |
| - name: Deploy to Staging using Terraform | |
| run: | | |
| cd gitops-repo | |
| # Setup Mise for Terraform and Helm | |
| curl https://mise.run | sh | |
| export PATH="$HOME/.local/bin:$PATH" | |
| # Install dependencies | |
| mise install | |
| # Deploy using existing mise command | |
| mise run deploy:up:k8s dev | |
| - name: Notify Deployment | |
| run: | | |
| echo "🚀 Staging deployment completed!" | |
| echo "Server image: ${{ needs.build-and-deploy-server.outputs.server-image-tag }}" | |
| echo "Dashboard image: ${{ needs.build-and-deploy-dashboard.outputs.dashboard-image-tag }}" | |
| echo "Commit: ${{ github.sha }}" |