Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .github/workflows/canary-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Update Canary PR Comment

permissions:
pull-requests: write
actions: read

on:
workflow_run:
workflows: ['Canary Deploy']
types: [completed]

jobs:
update-comment:
# Only run on the correct repository
if: github.repository == 'supabase/postgres-meta'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
# Get PR number from the workflow run
- name: Get PR info
id: pr-info
uses: actions/github-script@v7
with:
script: |
// Get the workflow run details
const workflowRun = context.payload.workflow_run;

// Find associated PR
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${workflowRun.head_repository.owner.login}:${workflowRun.head_branch}`
});

if (prs.data.length > 0) {
const pr = prs.data[0];
core.setOutput('pr_number', pr.number);
core.setOutput('found', 'true');
console.log(`Found PR #${pr.number}`);
} else {
core.setOutput('found', 'false');
console.log('No associated PR found');
}

# Only continue if we found a PR and the workflow succeeded
- name: Download canary info
if: ${{ steps.pr-info.outputs.found == 'true' && github.event.workflow_run.conclusion == 'success' }}
uses: actions/download-artifact@v4
with:
name: canary-info
path: canary-info/
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true

- name: Read canary info
if: ${{ steps.pr-info.outputs.found == 'true' && github.event.workflow_run.conclusion == 'success' }}
id: canary-info
run: |
if [ -f "canary-info/canary-tags.txt" ]; then
# Read the first tag (DockerHub) from the tags
FIRST_TAG=$(head -n1 canary-info/canary-tags.txt)
echo "tag=$FIRST_TAG" >> $GITHUB_OUTPUT
echo "found=true" >> $GITHUB_OUTPUT
echo "commit-sha=$(cat canary-info/commit-sha.txt)" >> $GITHUB_OUTPUT
else
echo "found=false" >> $GITHUB_OUTPUT
fi
continue-on-error: true

# Find existing comment
- name: Find existing comment
if: ${{ steps.pr-info.outputs.found == 'true' }}
uses: peter-evans/find-comment@v3
id: find-comment
with:
issue-number: ${{ steps.pr-info.outputs.pr_number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- postgres-meta-canary-status -->'

# Create or update comment based on workflow status
- name: Create or update canary comment
if: ${{ steps.pr-info.outputs.found == 'true' }}
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ steps.pr-info.outputs.pr_number }}
body: |
<!-- postgres-meta-canary-status -->
## 🚀 Canary Deployment Status

${{ github.event.workflow_run.conclusion == 'success' && steps.canary-info.outputs.found == 'true' && format('✅ **Canary image deployed successfully!**

🐳 **Docker Image:** `{0}`
📝 **Commit:** `{1}`

You can test this canary deployment by pulling the image:
```bash
docker pull {0}
```

You can also set the version in a supabase local project by running:
```bash
echo "{0}" > supabase/.temp/pgmeta-version
```

Or use it in your docker-compose.yml:
```yaml
services:
postgres-meta:
image: {0}
# ... other configuration
```

The canary image is available on:
- 🐳 [Docker Hub](https://hub.docker.com/r/supabase/postgres-meta)
- 📦 [GitHub Container Registry](https://ghcr.io/supabase/postgres-meta)
- ☁️ [AWS ECR Public](https://gallery.ecr.aws/supabase/postgres-meta)
', steps.canary-info.outputs.tag, steps.canary-info.outputs.commit-sha) || '' }}

${{ github.event.workflow_run.conclusion == 'failure' && '❌ **Canary deployment failed**

Please check the [workflow logs](' }}${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.html_url || '' }}${{ github.event.workflow_run.conclusion == 'failure' && ') for more details.

Make sure your PR has the `deploy-canary` label and targets the `master` branch.' || '' }}

---
<sub>Last updated: ${{ github.event.workflow_run.updated_at }}</sub>
edit-mode: replace
123 changes: 123 additions & 0 deletions .github/workflows/canary-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Canary Deploy

permissions:
contents: read
pull-requests: read
packages: write
id-token: write

on:
pull_request:
types: [opened, synchronize, labeled]
paths:
- 'src/**'
- 'package.json'
- 'package-lock.json'
- 'tsconfig.json'
- 'Dockerfile'

jobs:
build-canary:
# Only run if PR has the 'deploy-canary' label, is on the correct repository, and targets master branch
if: |
github.repository == 'supabase/postgres-meta' &&
github.event.pull_request.base.ref == 'master' &&
contains(github.event.pull_request.labels.*.name, 'deploy-canary')
runs-on: ubuntu-22.04
timeout-minutes: 30
outputs:
canary-tag: ${{ steps.meta.outputs.tags }}
pr-number: ${{ github.event.pull_request.number }}
steps:
# Checkout fork code - safe because no secrets are available for building
- name: Checkout code
uses: actions/checkout@v5

# Log PR author for auditing
- name: Log PR author
run: |
echo "Canary deploy triggered by: ${{ github.event.pull_request.user.login }}"
echo "PR #${{ github.event.pull_request.number }} from fork: ${{ github.event.pull_request.head.repo.full_name }}"

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'

- name: Install dependencies and build
run: |
npm clean-install
npm run build

# Generate canary tag
- id: meta
uses: docker/metadata-action@v5
with:
images: |
supabase/postgres-meta
public.ecr.aws/supabase/postgres-meta
ghcr.io/supabase/postgres-meta
tags: |
type=raw,value=canary-pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}
type=raw,value=canary-pr-${{ github.event.pull_request.number }}

- uses: docker/setup-qemu-action@v3
with:
platforms: amd64,arm64
- uses: docker/setup-buildx-action@v3

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.PROD_AWS_ROLE }}
aws-region: us-east-1

- name: Login to ECR
uses: docker/login-action@v3
with:
registry: public.ecr.aws

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push canary image
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: |
org.opencontainers.image.title=postgres-meta-canary
org.opencontainers.image.description=Canary build for PR #${{ github.event.pull_request.number }}
org.opencontainers.image.source=${{ github.event.pull_request.head.repo.html_url }}
org.opencontainers.image.revision=${{ github.event.pull_request.head.sha }}
canary.pr.number=${{ github.event.pull_request.number }}
canary.pr.author=${{ github.event.pull_request.user.login }}

# Save canary info for the comment workflow
- name: Save canary info
run: |
mkdir -p canary-info
echo "${{ steps.meta.outputs.tags }}" > canary-info/canary-tags.txt
echo "${{ github.event.pull_request.number }}" > canary-info/pr-number.txt
echo "${{ github.event.pull_request.head.sha }}" > canary-info/commit-sha.txt
echo "postgres-meta" > canary-info/package-name.txt

- name: Upload canary info
uses: actions/upload-artifact@v4
with:
name: canary-info
path: canary-info/
retention-days: 7
25 changes: 24 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,27 @@
2. Run the tests: `npm run test:run`
3. Make changes in code (`/src`) and tests (`/test/lib` and `/test/server`)
4. Run the tests again: `npm run test:run`
5. Commit + PR
5. Commit + PR

### Canary Deployments

For testing your changes when they impact other things (like type generation and postgrest-js), you can deploy a canary version of postgres-meta:

1. **Create a Pull Request** targeting the `master` branch
2. **Add the `deploy-canary` label** to your PR
3. **Wait for the canary build** - GitHub Actions will automatically build and push a canary Docker image
4. **Use the canary image** - The bot will comment on your PR with the exact image tag and usage instructions

The canary image will be tagged as:

- `supabase/postgres-meta:canary-pr-{PR_NUMBER}-{COMMIT_SHA}`
- `supabase/postgres-meta:canary-pr-{PR_NUMBER}`

Example usage:

```bash
docker pull supabase/postgres-meta:canary-pr-123-abc1234
echo "canary-pr-123-abc1234" > supabase/.temp/pgmeta-version
```

**Note:** Only maintainers can add the `deploy-canary` label for security reasons. The canary deployment requires access to production Docker registries.
Loading
Loading