diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e58bd32eb0..8dbdf4c6b1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @supabase/cli +* @supabase/cli \ No newline at end of file diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000000..e426edda97 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,30 @@ +name: Setup + +description: Perform standard setup and install dependencies using pnpm + +runs: + using: "composite" + steps: + - name: Install Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: latest + + - name: Install Node.js + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + with: + node-version-file: .nvmrc + package-manager-cache: false + + - name: Enable Corepack + shell: bash + run: npm install --global corepack && corepack enable + + - name: Configure dependency cache + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 + with: + cache: pnpm + + - name: Install dependencies + shell: bash + run: pnpm install --frozen-lockfile \ No newline at end of file diff --git a/.github/workflows/api-sync.yml b/.github/workflows/cli-go-api-sync.yml similarity index 95% rename from .github/workflows/api-sync.yml rename to .github/workflows/cli-go-api-sync.yml index 28fe129a5d..8500797adf 100644 --- a/.github/workflows/api-sync.yml +++ b/.github/workflows/cli-go-api-sync.yml @@ -5,8 +5,6 @@ on: types: - api-sync workflow_dispatch: # allow manual triggering - -# Add explicit permissions permissions: contents: write pull-requests: write @@ -20,7 +18,7 @@ jobs: - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true - name: Run codegen @@ -70,3 +68,6 @@ jobs: run: gh pr merge --auto --squash "${{ steps.cpr.outputs.pull-request-number }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/ci.yml b/.github/workflows/cli-go-ci.yml similarity index 88% rename from .github/workflows/ci.yml rename to .github/workflows/cli-go-ci.yml index 5ede9e3005..cae2d69889 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/cli-go-ci.yml @@ -2,10 +2,16 @@ name: CI on: pull_request: + paths: + - apps/cli-go/** merge_group: + paths: + - apps/cli-go/** push: branches: - develop + paths: + - apps/cli-go/** permissions: contents: read @@ -19,7 +25,7 @@ jobs: - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true # Required by: internal/utils/credentials/keyring_test.go @@ -56,7 +62,7 @@ jobs: - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod # Linter requires no cache cache: false @@ -73,7 +79,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true - run: go build main.go - run: ./main init @@ -90,13 +96,14 @@ jobs: link: name: Link - if: ${{ github.event_name == 'merge_group' || (github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork) }} + if: ${{ github.event_name == 'merge_group' || (github.event_name == + 'pull_request' && !github.event.pull_request.head.repo.fork) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true - run: go build main.go - run: ./main link @@ -112,7 +119,7 @@ jobs: - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true - run: go generate @@ -122,3 +129,6 @@ jobs: git diff exit 1 fi +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/cli-go-codeql.yml similarity index 86% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/cli-go-codeql.yml index 168bd09203..1c29daa44a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/cli-go-codeql.yml @@ -13,10 +13,16 @@ name: "CodeQL" on: pull_request: + paths: + - apps/cli-go/** merge_group: + paths: + - apps/cli-go/** push: branches: - develop + paths: + - apps/cli-go/** jobs: analyze: @@ -72,12 +78,12 @@ jobs: # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - if: matrix.build-mode == 'manual' shell: bash run: | @@ -92,3 +98,6 @@ jobs: uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: category: "/language:${{matrix.language}}" +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/mirror-image.yml b/.github/workflows/cli-go-mirror-image.yml similarity index 94% rename from .github/workflows/mirror-image.yml rename to .github/workflows/cli-go-mirror-image.yml index d3e34f2bf3..92250bd79f 100644 --- a/.github/workflows/mirror-image.yml +++ b/.github/workflows/cli-go-mirror-image.yml @@ -15,6 +15,8 @@ on: description: "org/image:tag" required: true type: string + paths: + - apps/cli-go/** permissions: contents: read @@ -48,3 +50,6 @@ jobs: dst: | public.ecr.aws/supabase/${{ steps.strip.outputs.image }} ghcr.io/supabase/${{ steps.strip.outputs.image }} +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/mirror.yml b/.github/workflows/cli-go-mirror.yml similarity index 93% rename from .github/workflows/mirror.yml rename to .github/workflows/cli-go-mirror.yml index df93dac907..ad6e3d5d2f 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/cli-go-mirror.yml @@ -15,7 +15,8 @@ on: # # TODO: Make the cli start test run *after* we mirror images (if needed). workflow_dispatch: - + paths: + - apps/cli-go/** permissions: contents: read @@ -29,7 +30,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version-file: go.mod + go-version-file: apps/cli-go/go.mod cache: true - id: list run: | @@ -58,3 +59,6 @@ jobs: with: image: ${{ matrix.src }} secrets: inherit +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/pg-prove.yml b/.github/workflows/cli-go-pg-prove.yml similarity index 94% rename from .github/workflows/pg-prove.yml rename to .github/workflows/cli-go-pg-prove.yml index 4d79abd601..792485e709 100644 --- a/.github/workflows/pg-prove.yml +++ b/.github/workflows/cli-go-pg-prove.yml @@ -2,7 +2,8 @@ name: Publish pg_prove on: workflow_dispatch: - + paths: + - apps/cli-go/** permissions: contents: read @@ -33,7 +34,7 @@ jobs: strategy: matrix: include: - - runner: [self-hosted, X64] + - runner: [ self-hosted, X64 ] arch: amd64 - runner: arm-runner arch: arm64 @@ -58,7 +59,8 @@ jobs: tags: ${{ needs.settings.outputs.image_tag }}_${{ matrix.arch }} platforms: linux/${{ matrix.arch }} cache-from: type=gha,scope=${{ github.ref_name }}-pg_prove-${{ matrix.arch }} - cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-pg_prove-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-pg_prove-${{ + matrix.arch }} merge_manifest: needs: @@ -86,3 +88,6 @@ jobs: with: image: ${{ needs.settings.outputs.image_tag }} secrets: inherit +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/publish-migra.yml b/.github/workflows/cli-go-publish-migra.yml similarity index 94% rename from .github/workflows/publish-migra.yml rename to .github/workflows/cli-go-publish-migra.yml index 65debc77e9..13caa28941 100644 --- a/.github/workflows/publish-migra.yml +++ b/.github/workflows/cli-go-publish-migra.yml @@ -2,7 +2,8 @@ name: Publish migra on: workflow_dispatch: - + paths: + - apps/cli-go/** permissions: contents: read @@ -33,7 +34,7 @@ jobs: strategy: matrix: include: - - runner: [self-hosted, X64] + - runner: [ self-hosted, X64 ] arch: amd64 - runner: arm-runner arch: arm64 @@ -58,7 +59,8 @@ jobs: tags: ${{ needs.settings.outputs.image_tag }}_${{ matrix.arch }} platforms: linux/${{ matrix.arch }} cache-from: type=gha,scope=${{ github.ref_name }}-migra-${{ matrix.arch }} - cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-migra-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-migra-${{ matrix.arch + }} merge_manifest: needs: @@ -86,3 +88,6 @@ jobs: with: image: ${{ needs.settings.outputs.image_tag }} secrets: inherit +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/tag-pkg.yml b/.github/workflows/cli-go-tag-pkg.yml similarity index 91% rename from .github/workflows/tag-pkg.yml rename to .github/workflows/cli-go-tag-pkg.yml index 8eaf266109..bf6c625585 100644 --- a/.github/workflows/tag-pkg.yml +++ b/.github/workflows/cli-go-tag-pkg.yml @@ -7,6 +7,8 @@ on: description: "pkg version to tag (e.g. v1.2.2)" required: true type: string + paths: + - apps/cli-go/** permissions: contents: write @@ -35,3 +37,6 @@ jobs: fi git tag "$TAG" git push origin "$TAG" +defaults: + run: + working-directory: apps/cli-go diff --git a/.github/workflows/deploy-check.yml b/.github/workflows/deploy-check.yml deleted file mode 100644 index 3715958a00..0000000000 --- a/.github/workflows/deploy-check.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Check Deploy - -on: - pull_request: - types: - - opened - - reopened - - synchronize - - edited - branches: - - main - -permissions: - contents: read - -jobs: - check: - if: github.head_ref != 'develop' - runs-on: ubuntu-latest - steps: - - run: | - echo "Pull requests to main branch are only allowed from develop branch." - exit 1 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 61ee1f603e..0000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Prod Deploy - -on: - # Run this action every Tuesday at 02:00 UTC (Singapore 10AM) - schedule: - - cron: "0 2 * * 2" - workflow_dispatch: - -permissions: - pull-requests: write - contents: write - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - - run: gh pr create -B main -H develop --title 'Prod deploy' --label 'do not merge' --fill - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml deleted file mode 100644 index 1eabd1aedf..0000000000 --- a/.github/workflows/install.yml +++ /dev/null @@ -1,136 +0,0 @@ -name: Install - -on: - pull_request: - paths: - - ".github/workflows/install.yml" - - "package.json" - - "scripts/**" - push: - branches: - - develop - paths: - - ".github/workflows/install.yml" - - "package.json" - - "scripts/**" - -permissions: - contents: read - -jobs: - pack: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - run: | - jq -c '.version = "1.28.0"' package.json > tmp.$$.json - mv tmp.$$.json package.json - npm pack - - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: installer - path: supabase-1.28.0.tgz - - npm: - needs: pack - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: installer - - - run: npm init -y - - run: npm i --save-dev ./supabase-1.28.0.tgz - - run: npx --no-install supabase --version - - yarn: - needs: pack - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: installer - - - run: yarn init -y - - run: yarn add -D ./supabase-1.28.0.tgz - - run: yarn supabase --version - - yarn_berry: - needs: pack - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: installer - - - run: yarn set version berry - # - run: yarn config set nodeLinker node-modules - - run: yarn init -y - # Yarn Berry 4.14+ disables install scripts by default (yarnpkg/berry#7089). - # The supabase package relies on a postinstall script to fetch its binary, - # so we opt in via YARN_ENABLE_SCRIPTS just for this install step (the - # Yarn analog to pnpm's --allow-build=supabase). - - run: yarn add -D ./supabase-1.28.0.tgz - env: - YARN_ENABLE_SCRIPTS: "true" - - if: ${{ matrix.os != 'windows-latest' }} - run: yarn supabase --version - # Workaround for running extensionless executable on windows - - if: ${{ matrix.os == 'windows-latest' }} - run: | - & "$(yarn bin supabase).exe" --version - - pnpm: - needs: pack - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: installer - - - run: npm install -g pnpm - - run: pnpm init - # https://github.com/pnpm/pnpm/issues/9124#issuecomment-2663021284 - - run: pnpm i --save-dev ./supabase-1.28.0.tgz --allow-build=supabase - - run: pnpm supabase --version - - bun: - needs: pack - strategy: - fail-fast: false - matrix: - # Bun build is experimental on windows - os: [ubuntu-latest, macos-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: installer - - - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - with: - bun-version: latest - - run: | - echo '{"trustedDependencies": ["supabase"]}' > package.json - - run: bun add -D ./supabase-1.28.0.tgz - - run: bunx supabase --version diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml new file mode 100644 index 0000000000..01d12c96b9 --- /dev/null +++ b/.github/workflows/release-alpha.yml @@ -0,0 +1,25 @@ +name: Release Alpha + +on: + workflow_dispatch: + inputs: + version: + description: Alpha npm package version to publish + required: true + type: string + dry_run: + description: Dry run (skip actual publishing) + required: false + type: boolean + default: true + +jobs: + release: + uses: ./.github/workflows/release-shared.yml + with: + version: ${{ inputs.version }} + shell: next + npm_tag: alpha + prerelease: true + dry_run: ${{ inputs.dry_run }} + secrets: inherit diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml deleted file mode 100644 index b529f8db26..0000000000 --- a/.github/workflows/release-beta.yml +++ /dev/null @@ -1,107 +0,0 @@ -name: Release (Beta) - -on: - push: - branches: - - develop - workflow_dispatch: - -permissions: - contents: read - -jobs: - release: - name: semantic-release - runs-on: ubuntu-latest - permissions: - contents: write - outputs: - new-release-published: ${{ steps.semantic-release.outputs.new_release_published }} - new-release-version: ${{ steps.semantic-release.outputs.new_release_version }} - new-release-channel: ${{ steps.semantic-release.outputs.new_release_channel }} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - id: semantic-release - uses: cycjimmy/semantic-release-action@b12c8f6015dc215fe37bc154d4ad456dd3833c90 # v6.0.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - goreleaser: - name: GoReleaser - needs: - - release - if: needs.release.outputs.new-release-published == 'true' - permissions: - contents: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - - uses: goreleaser/goreleaser-action@e24998b8b67b290c2fa8b7c14fcfa7de2c5c9b8c # v7.1.0 - with: - distribution: goreleaser - version: ~> v2 - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_ENDPOINT: ${{ secrets.POSTHOG_ENDPOINT }} - - - run: gh release edit v${{ needs.release.outputs.new-release-version }} --draft=false --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - commit: - name: Publish Brew and Scoop - needs: - - release - - goreleaser - if: needs.release.outputs.new-release-published == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - # use GitHub app to create a release token that can publish to homebrew-tap and scoop - - name: Generate token - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: | - homebrew-tap - scoop-bucket - - run: go run tools/publish/main.go --beta "${{ needs.release.outputs.new-release-version }}" - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - - publish: - name: Publish NPM - needs: - - release - - goreleaser - if: needs.release.outputs.new-release-published == 'true' - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: latest - registry-url: https://registry.npmjs.org - - run: npm --git-tag-version=false version ${{ needs.release.outputs.new-release-version }} - - run: npm publish --tag ${{ needs.release.outputs.new-release-channel }} diff --git a/.github/workflows/release-shared.yml b/.github/workflows/release-shared.yml new file mode 100644 index 0000000000..0b959d2908 --- /dev/null +++ b/.github/workflows/release-shared.yml @@ -0,0 +1,157 @@ +name: Release Shared + +on: + workflow_call: + inputs: + version: + description: npm package version to publish + required: true + type: string + shell: + description: CLI shell to package as the shipped supabase binary + required: true + type: string + npm_tag: + description: npm dist-tag to publish under + required: true + type: string + prerelease: + description: Whether the GitHub release should be marked as a prerelease + required: true + type: boolean + dry_run: + description: Dry run (skip actual publishing) + required: true + type: boolean + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup + uses: ./.github/actions/setup + + - name: Install nfpm + run: | + echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list + sudo apt-get update + sudo apt-get install -y nfpm + + - name: Sync versions + run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version ${{ inputs.version }} + + - name: Build selected shell + run: pnpm exec bun apps/cli/scripts/build.ts --version ${{ inputs.version }} --shell ${{ inputs.shell }} + + - name: Verify build artifacts + run: | + for pkg in cli-darwin-arm64 cli-darwin-x64 cli-linux-arm64 cli-linux-arm64-musl cli-linux-x64 cli-linux-x64-musl cli-windows-arm64 cli-windows-x64; do + echo "Checking packages/$pkg/bin/..." + ls -la "packages/$pkg/bin/" + done + echo "Checking dist/..." + ls -la dist/ + + - name: Upload build artifacts + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: cli-build-${{ inputs.shell }}-${{ inputs.version }} + path: | + packages/cli-*/bin/ + dist/ + + smoke-test: + needs: build + strategy: + fail-fast: false + matrix: + runner: [ubuntu-latest, macos-latest, macos-15-intel, windows-latest] + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup + uses: ./.github/actions/setup + + - name: Download build artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: cli-build-${{ inputs.shell }}-${{ inputs.version }} + + - name: Setup QEMU for cross-platform Docker + if: runner.os == 'Linux' + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 + + - name: Install Scoop + if: runner.os == 'Windows' + shell: pwsh + run: | + iex "& {$(irm get.scoop.sh)} -RunAsAdmin" + Join-Path (Resolve-Path ~).Path "scoop\shims" >> $env:GITHUB_PATH + + - name: Fix binary permissions + if: runner.os != 'Windows' + run: chmod +x packages/cli-*/bin/supabase || true + + - name: Run smoke tests + run: pnpm run test:smoke -- --version ${{ inputs.version }} --tag ${{ inputs.npm_tag }} + working-directory: apps/cli + + publish: + needs: smoke-test + if: ${{ !inputs.dry_run }} + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup + uses: ./.github/actions/setup + + - name: Download build artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: cli-build-${{ inputs.shell }}-${{ inputs.version }} + + - name: Sync versions + run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version ${{ inputs.version }} + + - name: Publish to npm + run: pnpm exec bun apps/cli/scripts/publish.ts --tag ${{ inputs.npm_tag }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create draft GitHub Release + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 + with: + tag_name: v${{ inputs.version }} + name: v${{ inputs.version }} + draft: true + prerelease: ${{ inputs.prerelease }} + files: | + dist/supabase_${{ inputs.version }}_darwin_arm64.tar.gz + dist/supabase_${{ inputs.version }}_darwin_amd64.tar.gz + dist/supabase_${{ inputs.version }}_linux_arm64.tar.gz + dist/supabase_${{ inputs.version }}_linux_amd64.tar.gz + dist/supabase_${{ inputs.version }}_linux_arm64.deb + dist/supabase_${{ inputs.version }}_linux_amd64.deb + dist/supabase_${{ inputs.version }}_linux_arm64.rpm + dist/supabase_${{ inputs.version }}_linux_amd64.rpm + dist/supabase_${{ inputs.version }}_linux_arm64.apk + dist/supabase_${{ inputs.version }}_linux_amd64.apk + dist/supabase_${{ inputs.version }}_windows_amd64.zip + dist/supabase_${{ inputs.version }}_windows_arm64.zip + dist/checksums.txt + + - name: Publish GitHub Release (immutable) + env: + GH_TOKEN: ${{ github.token }} + run: gh release edit v${{ inputs.version }} --draft=false diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml new file mode 100644 index 0000000000..a026d6784b --- /dev/null +++ b/.github/workflows/release-stable.yml @@ -0,0 +1,25 @@ +name: Release Stable + +on: + workflow_dispatch: + inputs: + version: + description: Stable npm package version to publish + required: true + type: string + dry_run: + description: Dry run (skip actual publishing) + required: false + type: boolean + default: true + +jobs: + release: + uses: ./.github/workflows/release-shared.yml + with: + version: ${{ inputs.version }} + shell: legacy + npm_tag: latest + prerelease: false + dry_run: ${{ inputs.dry_run }} + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 1fba8c4ae8..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,133 +0,0 @@ -name: Release - -on: - pull_request_review: - types: - - submitted - -permissions: - contents: read - -jobs: - fast-forward: - if: | - github.event.pull_request.head.ref == 'develop' && - github.event.pull_request.base.ref == 'main' && - github.event.review.state == 'approved' - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - outputs: - release_tag: ${{ steps.latest-release.outputs.tagName }} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - - run: | - git checkout main - git merge --ff-only "${{ github.event.pull_request.head.sha }}" - git push origin main - - id: latest-release - run: | - latest=$(gh release list --limit 1 --json tagName --jq '.[].tagName') - gh release edit $latest --latest --prerelease=false - echo "tagName=$latest" >> $GITHUB_OUTPUT - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - commit: - name: Publish Brew and Scoop - needs: - - fast-forward - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: | - homebrew-tap - scoop-bucket - - run: go run tools/publish/main.go ${{ needs.fast-forward.outputs.release_tag }} - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - - compose: - name: Bump self-hosted versions - needs: - - fast-forward - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: | - supabase - - run: go run tools/selfhost/main.go - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - - changelog: - name: Publish changelog - needs: - - fast-forward - - commit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: | - supabase - cli - - run: go run tools/changelog/main.go ${{ secrets.SLACK_CHANNEL }} - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }} - - docs: - name: Publish reference docs - needs: - - fast-forward - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 - with: - go-version-file: go.mod - cache: true - - id: app-token - uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: | - supabase - - run: go run docs/main.go ${{ needs.fast-forward.outputs.release_tag }} | go run tools/bumpdoc/main.go apps/docs/spec/cli_v1_commands.yaml - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/tag-npm.yml b/.github/workflows/tag-npm.yml deleted file mode 100644 index 6206b422ec..0000000000 --- a/.github/workflows/tag-npm.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Tag NPM - -on: - workflow_call: - inputs: - release: - required: true - type: string - workflow_dispatch: - inputs: - release: - description: "v1.0.0" - required: true - type: string - -permissions: - contents: read - id-token: write - -jobs: - tag: - name: Move latest tag - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: latest - registry-url: https://registry.npmjs.org - - - run: npm dist-tag add "supabase@${RELEASE_TAG#v}" latest - env: - RELEASE_TAG: ${{ inputs.release }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..9078d762ef --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,182 @@ +name: Test + +on: + push: + branches: + - develop + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + branches: + - develop + +permissions: + contents: read + actions: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: true + +jobs: + check: + if: github.event.pull_request.draft == false || github.event_name == 'push' + name: Check code quality + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup + uses: ./.github/actions/setup + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: apps/cli-go/go.mod + cache-dependency-path: apps/cli-go/go.sum + - name: Install golangci-lint + run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest && + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + - name: Unlock keyring (for cli-go keyring tests) + uses: t1m0thyj/unlock-keyring@cbcf205c879ebd86add70bab3a6abfcce59a5cae + + - name: Check code quality + run: pnpm run check:all + + test-core: + if: github.event.pull_request.draft == false || github.event_name == 'push' + name: Run unit and integration tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup + uses: ./.github/actions/setup + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: apps/cli-go/go.mod + cache-dependency-path: apps/cli-go/go.sum + - name: Install golangci-lint + run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest && + echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" + - name: Unlock keyring (for cli-go keyring tests) + uses: t1m0thyj/unlock-keyring@cbcf205c879ebd86add70bab3a6abfcce59a5cae + + - name: Run unit and integration tests + run: pnpm run test:core + + test-e2e: + if: github.event.pull_request.draft == false || github.event_name == 'push' + name: Run end-to-end tests (shard ${{ matrix.shard }}/3) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + shard: [ 1, 2, 3 ] + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 0 + + - name: Set base and head SHAs for affected + if: github.event_name == 'pull_request' + uses: nrwl/nx-set-shas@v4 + + - name: Setup + uses: ./.github/actions/setup + + # Detect which e2e suites should run. On PR we honour `nx affected` + # (using `NX_BASE`/`NX_HEAD` set by `nx-set-shas` above); on push we run + # everything that has a `test:e2e` target. + - name: Detect affected e2e projects + id: detect + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + affected=$(pnpm exec nx show projects --affected --withTarget test:e2e --json | jq -r '.[]') + else + affected=$(pnpm exec nx show projects --withTarget test:e2e --json | jq -r '.[]') + fi + echo "Affected e2e projects:" + echo "$affected" + cli=false + other=false + if echo "$affected" | grep -qx '@supabase/cli-e2e'; then cli=true; fi + if echo "$affected" | grep -vx '@supabase/cli-e2e' | grep -q .; then other=true; fi + echo "cli_e2e=$cli" >> "$GITHUB_OUTPUT" + echo "other=$other" >> "$GITHUB_OUTPUT" + + - name: Cache Go CLI binary + if: steps.detect.outputs.cli_e2e == 'true' + id: cache-go-binary + uses: actions/cache@v4 + with: + path: apps/cli-go/supabase-go + key: go-cli-${{ runner.os }}-${{ hashFiles('apps/cli-go/**/*.go', + 'apps/cli-go/go.mod', 'apps/cli-go/go.sum') }} + + - name: Setup Go + if: steps.detect.outputs.cli_e2e == 'true' && + steps.cache-go-binary.outputs.cache-hit != 'true' + uses: actions/setup-go@v5 + with: + go-version-file: apps/cli-go/go.mod + cache-dependency-path: apps/cli-go/go.sum + + - name: Build Go CLI + if: steps.detect.outputs.cli_e2e == 'true' && + steps.cache-go-binary.outputs.cache-hit != 'true' + run: go build -o supabase-go . + working-directory: apps/cli-go + + # The ts-legacy harness invokes `bun apps/cli/dist/main-legacy.js`; the + # `nx run @supabase/cli-e2e:test:e2e` target normally builds @supabase/cli + # via `dependsOn`, but we bypass nx for sharding so we build it explicitly. + - name: Build CLI + if: steps.detect.outputs.cli_e2e == 'true' + run: pnpm exec nx run @supabase/cli:build + + # Sharding for cli-e2e (the heavy suite) per + # https://vitest.dev/guide/improving-performance.html#sharding. We invoke + # vitest directly because routing `--shard` through `pnpm run / nx run-many + # -- --shard=N/3` introduces a stray `--` that vitest treats as a + # positional-argument terminator, defeating the shard flag. Other e2e + # suites (process-compose) run unsharded on shard 1. + - name: Run cli-e2e end-to-end tests + if: steps.detect.outputs.cli_e2e == 'true' + run: pnpm --filter @supabase/cli-e2e exec bun --bun vitest run --shard=${{ + matrix.shard }}/3 + env: + CLI_HARNESS_TARGET: ts-legacy + SUPABASE_GO_BINARY: ${{ github.workspace }}/apps/cli-go/supabase-go + + - name: Run other e2e tests (shard 1 only) + if: matrix.shard == 1 && steps.detect.outputs.other == 'true' + run: pnpm exec nx run-many -t test:e2e --exclude=@supabase/cli-e2e + env: + SUPABASE_GO_BINARY: ${{ github.workspace }}/apps/cli-go/supabase-go + + # Summary job that gates branch protection. The matrix `test-e2e` job + # produces per-shard check names (`Run end-to-end tests (shard N/3)`), so + # this job preserves the original `Run end-to-end tests` check name that + # branch protection rules already require. It succeeds iff every shard + # succeeded (or skipped — `success()` is true for skipped jobs). + test-e2e-summary: + if: always() && (github.event.pull_request.draft == false || github.event_name + == 'push') + name: Run end-to-end tests + needs: test-e2e + runs-on: ubuntu-latest + steps: + - name: Verify all shards succeeded + run: | + if [ "${{ needs.test-e2e.result }}" = "failure" ] || [ "${{ needs.test-e2e.result }}" = "cancelled" ]; then + echo "::error ::One or more e2e shards failed: ${{ needs.test-e2e.result }}" + exit 1 + fi + echo "All e2e shards reported: ${{ needs.test-e2e.result }}" diff --git a/.gitignore b/.gitignore index e119d97252..789bb71712 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,19 @@ -# General -.DS_Store +node_modules +dist +coverage/ .env +.claude/ +.agents/.repos/effect-v3 +.worktrees/ +.supabase/ +.idea/ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -/cli - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out +# Local dev registry (verdaccio storage, generated config, auth tokens) +tmp/ -# Dependency directories (remove the comment below to include it) -# vendor/ - -# IDE -/.vscode -/.idea - -# NPM -node_modules -package-lock.json +# Compiled CLI binaries (generated by build scripts, not source-controlled) +packages/cli-*/bin/ -# Initialized by cli for local testing -/supabase +# Nx +.nx/cache +.nx/workspace-data \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..1d6a09bd7c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,21 @@ +[submodule ".repos/effect"] + path = .repos/effect + url = https://github.com/Effect-TS/effect-smol.git +[submodule ".repos/effect-patterns"] + path = .repos/effect-patterns + url = https://github.com/PaulJPhilp/EffectPatterns +[submodule ".repos/effect-v3"] + path = .repos/effect-v3 + url = https://github.com/Effect-TS/effect.git +[submodule ".repos/lalph"] + path = .repos/lalph + url = https://github.com/tim-smart/lalph.git +[submodule ".repos/cheffect"] + path = .repos/cheffect + url = https://github.com/tim-smart/cheffect.git +[submodule ".repos/process-compose"] + path = .repos/process-compose + url = https://github.com/F1bonacc1/process-compose.git +[submodule ".repos/t3code"] + path = .repos/t3code + url = https://github.com/pingdotgg/t3code.git diff --git a/.goreleaser.yml b/.goreleaser.yml deleted file mode 100644 index 98e3cef593..0000000000 --- a/.goreleaser.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: 2 -project_name: supabase -builds: - - id: supabase - binary: supabase - flags: - - -trimpath - ldflags: - - -s -w -X github.com/supabase/cli/internal/utils.Version={{.Version}} -X github.com/supabase/cli/internal/utils.SentryDsn={{ .Env.SENTRY_DSN }} -X github.com/supabase/cli/internal/utils.PostHogAPIKey={{ .Env.POSTHOG_API_KEY }} -X github.com/supabase/cli/internal/utils.PostHogEndpoint={{ .Env.POSTHOG_ENDPOINT }} - env: - - CGO_ENABLED=0 - targets: - - darwin_amd64 - - darwin_arm64 - - linux_amd64 - - linux_arm64 - - windows_amd64 - - windows_arm64 -archives: - - name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}' -release: - draft: true - replace_existing_draft: true - prerelease: auto -changelog: - use: github - groups: - - title: Features - regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' - order: 0 - - title: "Bug fixes" - regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' - order: 1 - - title: Others - order: 999 -nfpms: - - vendor: Supabase - description: Supabase CLI - maintainer: Supabase CLI - homepage: https://supabase.com - license: MIT - formats: - - apk - - deb - - rpm - - archlinux diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..cabf43b5dd --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24 \ No newline at end of file diff --git a/.repos/cheffect b/.repos/cheffect new file mode 160000 index 0000000000..f4c923c96b --- /dev/null +++ b/.repos/cheffect @@ -0,0 +1 @@ +Subproject commit f4c923c96b7153671b4a2c9474c1e7e03ab8f36c diff --git a/.repos/effect b/.repos/effect new file mode 160000 index 0000000000..aae8797b9c --- /dev/null +++ b/.repos/effect @@ -0,0 +1 @@ +Subproject commit aae8797b9cb383be0c182dd58d03d787c354238b diff --git a/.repos/effect-patterns b/.repos/effect-patterns new file mode 160000 index 0000000000..f3a0da2299 --- /dev/null +++ b/.repos/effect-patterns @@ -0,0 +1 @@ +Subproject commit f3a0da2299717cf31d31313c5661cebd2446d5a3 diff --git a/.repos/effect-v3 b/.repos/effect-v3 new file mode 160000 index 0000000000..70ce155cd7 --- /dev/null +++ b/.repos/effect-v3 @@ -0,0 +1 @@ +Subproject commit 70ce155cd73a3b4cd723fe955454b5837b428f76 diff --git a/.repos/lalph b/.repos/lalph new file mode 160000 index 0000000000..203f1ec28f --- /dev/null +++ b/.repos/lalph @@ -0,0 +1 @@ +Subproject commit 203f1ec28f26d3a4f18c0f3e092eae3695de1842 diff --git a/.repos/process-compose b/.repos/process-compose new file mode 160000 index 0000000000..cd7f6af235 --- /dev/null +++ b/.repos/process-compose @@ -0,0 +1 @@ +Subproject commit cd7f6af235149a075385f3b8b54d635e83dc0f52 diff --git a/.repos/t3code b/.repos/t3code new file mode 160000 index 0000000000..91a03e0747 --- /dev/null +++ b/.repos/t3code @@ -0,0 +1 @@ +Subproject commit 91a03e074751e9dc732d0dddcd7b3a291caba34f diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..aada68d804 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oven.bun-vscode", "oxc.oxc-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..0ff9ffd7c9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "typescript.experimental.useTsgo": true, + "oxc.useExecPath": true, +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..d252664133 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,223 @@ +# Supabase + +Bun monorepo with workspaces under `apps/` and `packages/`. + +## Package Manager + +`pnpm` is the package manager. Use `pnpm