fix: correct CORS allowed origins configuration in main.go #10
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
| # Registry Deploy: test both components, build arm64 images (selective), push to ECR, deploy to EC2. | |
| # | |
| # Triggers: | |
| # - Push to main touching api/** or web/** or this workflow → build & deploy only what changed | |
| # - Manual dispatch: choose API only, Web only, or both (default) | |
| name: Registry Deploy | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "api/**" | |
| - "web/**" | |
| - ".github/workflows/deploy.yml" | |
| workflow_dispatch: | |
| inputs: | |
| force: | |
| description: "Force deploy (skip tests)" | |
| type: boolean | |
| default: false | |
| deploy_api: | |
| description: "Deploy API" | |
| type: boolean | |
| default: true | |
| deploy_web: | |
| description: "Deploy Web" | |
| type: boolean | |
| default: true | |
| concurrency: | |
| group: registry-deploy | |
| cancel-in-progress: false | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| # ── What to build (path filter on push; inputs on manual) ───────────────── | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| build_api: ${{ steps.set.outputs.build_api }} | |
| build_web: ${{ steps.set.outputs.build_web }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: dorny/paths-filter@v3 | |
| id: paths | |
| with: | |
| filters: | | |
| api: 'api/**' | |
| web: 'web/**' | |
| - id: set | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "build_api=${{ inputs.deploy_api }}" >> $GITHUB_OUTPUT | |
| echo "build_web=${{ inputs.deploy_web }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "build_api=${{ steps.paths.outputs.api }}" >> $GITHUB_OUTPUT | |
| echo "build_web=${{ steps.paths.outputs.web }}" >> $GITHUB_OUTPUT | |
| fi | |
| # ── Tests ────────────────────────────────────────────────────────────── | |
| test-api: | |
| if: ${{ !inputs.force }} | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_DB: test | |
| POSTGRES_USER: test | |
| POSTGRES_PASSWORD: test | |
| ports: | |
| - "5432:5432" | |
| options: --health-cmd "pg_isready -U test" --health-interval 5s | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.24" | |
| cache: true | |
| cache-dependency-path: api/go.sum | |
| - name: Run Go tests | |
| run: go test ./... -race -coverprofile=coverage.out | |
| working-directory: api | |
| env: | |
| DATABASE_URL: postgres://test:test@localhost:5432/test?sslmode=disable | |
| - name: Run go vet | |
| run: go vet ./... | |
| working-directory: api | |
| test-web: | |
| if: ${{ !inputs.force }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| working-directory: web | |
| - name: Typecheck | |
| run: bun run tsc -b | |
| working-directory: web | |
| # ── Build & Push ─────────────────────────────────────────────────────── | |
| build-and-push: | |
| needs: [changes, test-api, test-web] | |
| if: | | |
| always() && | |
| (needs.test-api.result == 'success' || needs.test-api.result == 'skipped') && | |
| (needs.test-web.result == 'success' || needs.test-web.result == 'skipped') && | |
| (needs.changes.outputs.build_api == 'true' || needs.changes.outputs.build_web == 'true') && | |
| github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| outputs: | |
| image-tag: ${{ github.sha }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/devsper-deploy | |
| aws-region: us-east-1 | |
| - uses: aws-actions/amazon-ecr-login@v2 | |
| id: ecr-login | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Build and push API image | |
| if: needs.changes.outputs.build_api == 'true' | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: api | |
| platforms: linux/arm64 | |
| push: true | |
| tags: | | |
| ${{ steps.ecr-login.outputs.registry }}/devsper-registry-api:latest | |
| ${{ steps.ecr-login.outputs.registry }}/devsper-registry-api:${{ github.sha }} | |
| cache-from: type=gha,scope=registry-api | |
| cache-to: type=gha,mode=max,scope=registry-api | |
| - name: Build and push Web image | |
| if: needs.changes.outputs.build_web == 'true' | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: web | |
| platforms: linux/arm64 | |
| push: true | |
| tags: | | |
| ${{ steps.ecr-login.outputs.registry }}/devsper-registry-web:latest | |
| ${{ steps.ecr-login.outputs.registry }}/devsper-registry-web:${{ github.sha }} | |
| cache-from: type=gha,scope=registry-web | |
| cache-to: type=gha,mode=max,scope=registry-web | |
| # ── Deploy ───────────────────────────────────────────────────────────── | |
| deploy: | |
| needs: [build-and-push, changes] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| env: | |
| EC2_HOST: ${{ vars.REGISTRY_EC2_HOST }} | |
| EC2_INSTANCE_ID: ${{ vars.REGISTRY_EC2_INSTANCE_ID }} | |
| ECR_REGISTRY: ${{ vars.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com | |
| IMAGE_TAG: ${{ needs.build-and-push.outputs.image-tag }} | |
| steps: | |
| - uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/devsper-deploy | |
| aws-region: us-east-1 | |
| - name: Deploy via EC2 Instance Connect | |
| env: | |
| DEPLOY_API: ${{ needs.changes.outputs.build_api }} | |
| DEPLOY_WEB: ${{ needs.changes.outputs.build_web }} | |
| run: | | |
| ssh-keygen -t ed25519 -f /tmp/deploy_key -N "" -q | |
| aws ec2-instance-connect send-ssh-public-key \ | |
| --instance-id "$EC2_INSTANCE_ID" \ | |
| --instance-os-user ubuntu \ | |
| --ssh-public-key file:///tmp/deploy_key.pub | |
| # Build compose up args from what we deployed | |
| UP_ARGS="" | |
| if [ "$DEPLOY_API" = "true" ] && [ "$DEPLOY_WEB" = "true" ]; then | |
| UP_ARGS="web api" | |
| elif [ "$DEPLOY_WEB" = "true" ]; then | |
| UP_ARGS="web" | |
| elif [ "$DEPLOY_API" = "true" ]; then | |
| UP_ARGS="api" | |
| fi | |
| ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no ubuntu@"$EC2_HOST" \ | |
| "set -euo pipefail && \ | |
| aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $ECR_REGISTRY && \ | |
| cd /opt/devsper-registry && \ | |
| docker compose -f docker-compose.prod.yml --env-file .env.prod pull $UP_ARGS && \ | |
| ([ \"$DEPLOY_WEB\" = true ] && docker compose -f docker-compose.prod.yml --env-file .env.prod up -d --no-deps web || true) && \ | |
| sleep 3 && \ | |
| ([ \"$DEPLOY_API\" = true ] && docker compose -f docker-compose.prod.yml --env-file .env.prod up -d --no-deps api || true) && \ | |
| docker image prune -f" | |
| rm -f /tmp/deploy_key /tmp/deploy_key.pub | |
| - name: Smoke test | |
| env: | |
| DEPLOY_API: ${{ needs.changes.outputs.build_api }} | |
| DEPLOY_WEB: ${{ needs.changes.outputs.build_web }} | |
| run: | | |
| echo "Waiting for services to stabilize..." | |
| sleep 15 | |
| BASE="https://registry.devsper.com" | |
| CURL_OPTS="-sf --retry 5 --retry-delay 8 --retry-all-errors" | |
| if [ "$DEPLOY_API" = "true" ]; then | |
| echo "Checking API..." | |
| curl $CURL_OPTS "$BASE/health" || { echo "FAIL: /health"; exit 1; } | |
| curl $CURL_OPTS "$BASE/auth/jwks" || { echo "FAIL: /auth/jwks"; exit 1; } | |
| curl $CURL_OPTS "$BASE/api/v1/packages" || { echo "FAIL: /api/v1/packages"; exit 1; } | |
| fi | |
| if [ "$DEPLOY_WEB" = "true" ]; then | |
| echo "Checking web..." | |
| curl $CURL_OPTS "$BASE/" || { echo "FAIL: / (web)"; exit 1; } | |
| fi | |
| echo "All smoke tests passed" |