|
| 1 | +name: Deploy Catalog to GCP (catalog.vectorinstitute.ai) |
| 2 | + |
| 3 | +on: |
| 4 | + push: |
| 5 | + branches: |
| 6 | + - main |
| 7 | + paths: |
| 8 | + - 'catalog/**' |
| 9 | + - 'repositories/**' |
| 10 | + - 'scripts/sync_repositories_to_json.py' |
| 11 | + - 'scripts/collect_pypi_metrics.py' |
| 12 | + - '.github/workflows/deploy-catalog-gcp.yml' |
| 13 | + workflow_dispatch: |
| 14 | + # Auto-trigger when metrics are updated |
| 15 | + workflow_run: |
| 16 | + workflows: ["Collect GitHub Metrics"] |
| 17 | + types: |
| 18 | + - completed |
| 19 | + branches: |
| 20 | + - main |
| 21 | + |
| 22 | +permissions: |
| 23 | + contents: read |
| 24 | + id-token: write |
| 25 | + |
| 26 | +concurrency: |
| 27 | + group: "gcp-catalog-deploy" |
| 28 | + cancel-in-progress: false |
| 29 | + |
| 30 | +jobs: |
| 31 | + build-and-deploy: |
| 32 | + runs-on: ubuntu-latest |
| 33 | + # Only deploy if metrics collection succeeded (or if triggered by push/manual) |
| 34 | + if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} |
| 35 | + |
| 36 | + steps: |
| 37 | + - name: Checkout |
| 38 | + uses: actions/checkout@v6 |
| 39 | + |
| 40 | + - name: Setup Node.js |
| 41 | + uses: actions/setup-node@v6 |
| 42 | + with: |
| 43 | + node-version: '20' |
| 44 | + cache: 'npm' |
| 45 | + cache-dependency-path: catalog/package-lock.json |
| 46 | + |
| 47 | + - name: Install uv |
| 48 | + uses: astral-sh/setup-uv@v7 |
| 49 | + with: |
| 50 | + version: "0.9.11" |
| 51 | + enable-cache: true |
| 52 | + |
| 53 | + - name: Set up Python |
| 54 | + uses: actions/setup-python@v6 |
| 55 | + with: |
| 56 | + python-version: '3.12' |
| 57 | + |
| 58 | + - name: Install Python dependencies |
| 59 | + run: uv pip install --system pyyaml requests |
| 60 | + |
| 61 | + - name: Sync YAML repositories to JSON |
| 62 | + run: python scripts/sync_repositories_to_json.py |
| 63 | + |
| 64 | + - name: Collect PyPI metrics |
| 65 | + run: python scripts/collect_pypi_metrics.py |
| 66 | + continue-on-error: true |
| 67 | + |
| 68 | + - name: Install Node dependencies |
| 69 | + working-directory: catalog |
| 70 | + run: npm ci |
| 71 | + |
| 72 | + - name: Build Next.js site for GCP (root domain) |
| 73 | + working-directory: catalog |
| 74 | + run: npm run build |
| 75 | + env: |
| 76 | + # Build for root domain (no base path needed for catalog.vectorinstitute.ai) |
| 77 | + NODE_ENV: production |
| 78 | + |
| 79 | + - name: Authenticate to Google Cloud |
| 80 | + uses: google-github-actions/auth@v2 |
| 81 | + with: |
| 82 | + workload_identity_provider: 'projects/736624225747/locations/global/workloadIdentityPools/github-actions-pool/providers/github-provider' |
| 83 | + service_account: '[email protected]' |
| 84 | + |
| 85 | + - name: Set up Cloud SDK |
| 86 | + uses: google-github-actions/setup-gcloud@v2 |
| 87 | + |
| 88 | + - name: Deploy to GCS |
| 89 | + run: | |
| 90 | + # Sync files to GCS bucket |
| 91 | + gcloud storage rsync \ |
| 92 | + --recursive \ |
| 93 | + --delete-unmatched-destination-objects \ |
| 94 | + catalog/out/ \ |
| 95 | + gs://catalog-vectorinstitute-ai/ |
| 96 | +
|
| 97 | + - name: Set cache headers for static assets |
| 98 | + run: | |
| 99 | + # Set cache headers for static assets (CSS, JS, images) |
| 100 | + # _next/static has immutable hashed filenames, so cache for 1 year |
| 101 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/_next/static/**" \ |
| 102 | + --cache-control="public, max-age=31536000, immutable" \ |
| 103 | + --recursive || true |
| 104 | +
|
| 105 | + # Cache other static assets for 1 hour |
| 106 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/_next/**" \ |
| 107 | + --cache-control="public, max-age=3600" \ |
| 108 | + --recursive || true |
| 109 | +
|
| 110 | + # HTML files should be revalidated frequently |
| 111 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/**.html" \ |
| 112 | + --cache-control="public, max-age=300, must-revalidate" \ |
| 113 | + --recursive || true |
| 114 | +
|
| 115 | + # Index files need fresh content |
| 116 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/index.html" \ |
| 117 | + --cache-control="public, max-age=60, must-revalidate" || true |
| 118 | +
|
| 119 | + - name: Set content types |
| 120 | + run: | |
| 121 | + # Ensure proper content types for common files |
| 122 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/**.json" \ |
| 123 | + --content-type="application/json" \ |
| 124 | + --recursive || true |
| 125 | +
|
| 126 | + gcloud storage objects update "gs://catalog-vectorinstitute-ai/**.xml" \ |
| 127 | + --content-type="application/xml" \ |
| 128 | + --recursive || true |
| 129 | +
|
| 130 | + - name: Deployment summary |
| 131 | + run: | |
| 132 | + echo "✅ Catalog deployed successfully to GCS!" |
| 133 | + echo "📦 Bucket: gs://catalog-vectorinstitute-ai" |
| 134 | + echo "🌐 Once load balancer is configured, it will be available at:" |
| 135 | + echo " https://catalog.vectorinstitute.ai" |
0 commit comments