From c339fcb4954bb0303cacbafdda87423a87d83352 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 12 Jul 2026 21:27:39 +0530 Subject: [PATCH 1/3] ci: deploy production through declarative config --- .github/workflows/production.yml | 88 ++++++++++++++++---------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 788a006..50f7653 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -4,22 +4,36 @@ on: release: types: [published] workflow_dispatch: + inputs: + tag: + description: Image tag to deploy + required: true + type: string + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false env: - TAG: ${{ github.event.release.tag_name || github.sha }} - REPOSITORY: mcp-for-docs + ENVIRONMENT: production + PROJECT: mcp-for-docs + DECLARATIVE_OWNER: appwrite-labs + DECLARATIVE_REPOSITORY: assets-applications + REGISTRY_GITHUB: ghcr.io + IMAGE_NAME: appwrite/mcp-for-docs + TAG: ${{ github.event.release.tag_name || inputs.tag }} jobs: build: runs-on: ubuntu-latest steps: - name: Checkout the repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Login to GHCR + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.REGISTRY_GITHUB }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} @@ -28,52 +42,40 @@ jobs: with: context: . push: true - tags: ghcr.io/appwrite/mcp-for-docs:${{ env.TAG }} + tags: ${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}:${{ env.TAG }} secrets: | OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} - deploy_kubernetes: - strategy: - matrix: - region: [{ full: fra1, short: fra }] + deploy: needs: build runs-on: ubuntu-latest steps: - - name: Checkout the repo - uses: actions/checkout@v4 - - name: Install Kubectl - uses: azure/setup-kubectl@v4 - - name: Install Helm - uses: azure/setup-helm@v4 - - name: Install doctl - uses: digitalocean/action-doctl@v2 + - name: Get token for ${{ env.DECLARATIVE_REPOSITORY }} + id: app-token + uses: actions/create-github-app-token@v2 with: - token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} - - name: Save DigitalOcean kubeconfig with short-lived credentials - run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 assets-${{ matrix.region.full }}-prod - - - name: Ensure namespaces exist - run: | - kubectl create namespace mcp-for-docs --dry-run=client -o yaml | kubectl apply -f - + app-id: ${{ vars.DECLARATIVE_DEPLOYMENT_GITHUB_APP_ID }} + private-key: ${{ secrets.DECLARATIVE_DEPLOYMENT_GITHUB_APP_PRIVATE_KEY }} + owner: ${{ env.DECLARATIVE_OWNER }} + repositories: ${{ env.DECLARATIVE_REPOSITORY }} - - name: Create docker pull secret - run: | - kubectl -n mcp-for-docs create secret docker-registry ghcr \ - --docker-server=ghcr.io \ - --docker-username="${{ secrets.GHCR_USERNAME }}" \ - --docker-password="${{ secrets.GHCR_TOKEN }}" \ - --docker-email=ci@appwrite.io \ - --dry-run=client -o yaml | kubectl apply -f - + - name: Checkout ${{ env.DECLARATIVE_REPOSITORY }} + uses: actions/checkout@v6 + with: + repository: ${{ env.DECLARATIVE_OWNER }}/${{ env.DECLARATIVE_REPOSITORY }} + token: ${{ steps.app-token.outputs.token }} - - name: Create application secrets - run: | - kubectl -n mcp-for-docs create secret generic mcp-for-docs \ - --from-literal=openai-api-key="${{ secrets.OPENAI_API_KEY }}" \ - --dry-run=client -o yaml | kubectl apply -f - + - name: Update image tag + run: yq -i '.global.image.tag = strenv(TAG)' ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/default.yaml - - name: Deploy + - name: Commit and push run: | - helm upgrade --install --namespace mcp-for-docs mcp-for-docs deploy/mcp-for-docs/ \ - --values deploy/mcp-for-docs/environments/production/${{ matrix.region.full }}.values.yaml \ - --set imagePullSecret='ghcr' \ - --set version=${{ env.TAG }} + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/default.yaml + if git diff --cached --quiet; then + echo "No changes to commit" + else + git commit -m "chore(${{ env.ENVIRONMENT }}): ${{ env.PROJECT }} image tag to ${{ env.TAG }}" + git push + fi From c28a896b0bd555cc401fb51e3d913066a24403ef Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 12 Jul 2026 21:30:34 +0530 Subject: [PATCH 2/3] fix: preserve release images on redeploy --- .github/workflows/production.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 50f7653..a415d3c 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -25,6 +25,7 @@ env: jobs: build: + if: github.event_name == 'release' runs-on: ubuntu-latest steps: - name: Checkout the repo @@ -48,6 +49,7 @@ jobs: deploy: needs: build + if: always() && (needs.build.result == 'success' || needs.build.result == 'skipped') runs-on: ubuntu-latest steps: - name: Get token for ${{ env.DECLARATIVE_REPOSITORY }} From 44f824905b68ee1f7f2459f607976b1f1362c1ab Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sun, 12 Jul 2026 21:33:58 +0530 Subject: [PATCH 3/3] fix: avoid expression injection in deploy script --- .github/workflows/production.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index a415d3c..e774094 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -78,6 +78,6 @@ jobs: if git diff --cached --quiet; then echo "No changes to commit" else - git commit -m "chore(${{ env.ENVIRONMENT }}): ${{ env.PROJECT }} image tag to ${{ env.TAG }}" + git commit -m "chore(${ENVIRONMENT}): ${PROJECT} image tag to ${TAG}" git push fi