diff --git a/.github/workflows/1_2_bump_extension_only.yml b/.github/workflows/1_2_bump_extension_only.yml deleted file mode 100644 index 1a2405333e..0000000000 --- a/.github/workflows/1_2_bump_extension_only.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: 1/2. Bump versions for extension only (on push to main and patch branch) - -# This workflow covers both '1_check_for_updates' and '2_bump_versions' workflows, therefore it is another variant of the same, but specifically for extension only, without any Prisma CLI updates that would need to be handled. - -on: - push: - branches: - - 'main' - - '**.x' - - '!renovate/**' - paths-ignore: - - '.github/**' - workflow_dispatch: - -concurrency: - group: version-management - cancel-in-progress: false - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 1_2_bump_extension_only.yml' - -jobs: - bump: - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: checkout main if necessary - if: endsWith(github.ref, '/main') == false - run: git fetch && git checkout main - - name: Install Dependencies - run: pnpm install - shell: bash - - name: Setup Git - run: | - sh scripts/set_git_credentials.sh - - name: Update extension version in scripts folder - id: update - run: node scripts/bump_extension_version.mjs extension-patch-release - - name: Commit and Push - run: | - sh scripts/commit_and_push.sh "[skip ci] bump extension version in scripts to ${{ steps.update.outputs.next_extension_version }}." - - - name: Checkout previous branch - if: endsWith(github.ref, '/main') == false - run: git checkout -f ${{ github.ref_name }} - - name: Update VS Code extension version - run: | - node scripts/update_package_json_files.mjs dev ${{ steps.update.outputs.next_extension_version }} "" - - name: Install Dependencies - run: pnpm install - - name: Commit and Push - run: | - sh scripts/commit_and_push.sh "[skip ci] bump extension version in package.json to ${{ steps.update.outputs.next_extension_version }}." ${{ steps.setup_branch.outputs.new_branch }} - - - name: Trigger next workflow for Language Server tests - if: endsWith(github.ref, '/main') - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 3. Test Language Server and publish - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "release_channel": "insider", "extension_version": "${{ steps.update.outputs.next_extension_version }}", "branch": "main", "trigger_reason": "Commit from ${{ github.ref_name }}" }' diff --git a/.github/workflows/1_2_stable_extension_release.yml b/.github/workflows/1_2_stable_extension_release.yml deleted file mode 100644 index 1a5a963c3f..0000000000 --- a/.github/workflows/1_2_stable_extension_release.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: 1/2. Bump and release a stable version of the extension, meant for manual releases - -# This workflow covers both '1_check_for_updates' and '2_bump_versions' workflows, therefore it is another variant of the same, but specifically for extension only, without any Prisma CLI updates that would need to be handled. - -on: - workflow_dispatch: - inputs: - release_type: - description: 'Type of release to perform' - required: true - type: choice - options: - - patch - - minor - - major - -concurrency: - group: version-management - cancel-in-progress: false - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 1_2_stable_extension_release.yml' - -jobs: - bump: - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Install Dependencies - run: pnpm install - shell: bash - - name: Setup Git - run: | - sh scripts/set_git_credentials.sh - - name: Update extension version in scripts folder - id: update - run: node scripts/bump_extension_version.mjs extension-${{ github.event.inputs.release_type }}-release - - name: Commit and Push - run: | - sh scripts/commit_and_push.sh "[skip ci] bump extension version in scripts to ${{ steps.update.outputs.next_extension_version }}." - - name: Update VS Code extension version - run: | - node scripts/update_package_json_files.mjs latest ${{ steps.update.outputs.next_extension_version }} "" - - name: Install Dependencies - run: pnpm install - - name: Commit and Push - run: | - sh scripts/commit_and_push.sh "[skip ci] bump extension version in package.json to ${{ steps.update.outputs.next_extension_version }}." - - - name: Trigger next workflow for Language Server tests - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 3. Test Language Server and publish - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "release_channel": "stable", "extension_version": "${{ steps.update.outputs.next_extension_version }}", "branch": "main", "trigger_reason": "Manual ${{ github.event.inputs.release_type }} stable extension release" }' diff --git a/.github/workflows/1_check_for_updates.yml b/.github/workflows/1_check_for_updates.yml deleted file mode 100644 index 0f54ed2c78..0000000000 --- a/.github/workflows/1_check_for_updates.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: 1. Check for Prisma CLI Update - -on: - # Scheduled trigger disabled: ORM iteration is paused; CLI-update polling - # runs on demand. Restore the `schedule:` block below to re-enable. - # schedule: - # - cron: '*/5 * * * *' - workflow_dispatch: - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 1_check_for_update.yml' - -jobs: - check: - name: Check for Prisma CLI update - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Install Dependencies - run: pnpm install - - # First it runs this - - name: Check for Prisma CLI update - id: check_update - run: node scripts/check_for_update.mjs - - # ... and depending on the output any (or none) of these 3: - - name: Invoke bump workflow with inputs for dev - if: ${{ steps.check_update.outputs.dev_version }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 2. Bump versions - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "npm_channel": "dev", "version": "${{ steps.check_update.outputs.dev_version }}" }' - - name: Invoke bump workflow with inputs for latest - if: ${{ steps.check_update.outputs.latest_version }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 2. Bump versions - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "npm_channel": "latest", "version": "${{ steps.check_update.outputs.latest_version }}" }' - - name: Invoke bump workflow with inputs for patch-dev - if: ${{ steps.check_update.outputs.patch-dev_version }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 2. Bump versions - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "npm_channel": "patch-dev", "version": "${{ steps.check_update.outputs.patch-dev_version }}" }' diff --git a/.github/workflows/2_bump_versions.yml b/.github/workflows/2_bump_versions.yml deleted file mode 100644 index 83e0e0b6b9..0000000000 --- a/.github/workflows/2_bump_versions.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: 2. Bump versions -run-name: 2. Bump versions - CLI ${{ inputs.version }} from ${{ inputs.npm_channel }} - -on: - workflow_dispatch: - inputs: - npm_channel: - description: 'Prisma CLI NPM Channel to bump' - required: true - type: choice - options: - - latest - - dev - - patch-dev - version: - description: 'New Prisma CLI version in that channel' - required: true - -concurrency: - group: version-management - cancel-in-progress: false - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 2_bump_versions.yml' - RELEASE_CHANNEL: ${{ github.event.inputs.npm_channel == 'latest' && 'stable' || 'insider' }} - -jobs: - bump: - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Install Dependencies - run: pnpm install - - name: Setup Git - run: | - sh scripts/set_git_credentials.sh - - name: Print inputs - run: | - echo ${{github.event.inputs.npm_channel}} - echo ${{github.event.inputs.version}} - - - name: Update versions file in scripts folder - run: | - echo "${{ github.event.inputs.version }}" >scripts/versions/prisma_${{ github.event.inputs.npm_channel }} - - if git diff --exit-code; then - echo "Version has not changed! We should not attempt to bump." - exit 1 - fi - - - name: Update next extension version in scripts folder and output for later use - id: update # Used to access the calculated next extension version in later steps - run: node scripts/bump_extension_version.mjs prisma-${{ github.event.inputs.npm_channel }}-release - - name: Commit and Push - run: | - sh scripts/commit_and_push.sh "[skip ci] bump Prisma CLI ${{ github.event.inputs.npm_channel }} version to ${{ github.event.inputs.version }} and extension version to ${{ steps.update.outputs.next_extension_version }} in scripts." - - - name: Switch branch - id: setup_branch - run: | - sh scripts/setup_branch.sh ${{ github.event.inputs.npm_channel }} - - name: Check for minor or major release - id: is_minor_or_major - run: | - VERSION_SCRIPT=$([ -f scripts/is_minor_or_major_release.mjs ] && echo "is_minor_or_major_release.mjs" || echo "is_minor_or_major_release.js") - node "scripts/$VERSION_SCRIPT" ${{ github.event.inputs.npm_channel }} - - name: Reset on 'main' branch if minor or major release - if: ${{steps.is_minor_or_major.outputs.is_minor_or_major_release}} - run: | - git reset --hard main - git push --force origin stable - - name: Update Prisma CLI version and VS Code extension version - run: | - node scripts/update_package_json_files.mjs ${{ github.event.inputs.npm_channel }} ${{ steps.update.outputs.next_extension_version }} ${{ github.event.inputs.version }} - - name: Install Dependencies to update lock file - run: pnpm install --frozen-lockfile=false - - name: Push to branch - run: | - sh scripts/commit_and_push.sh "[skip ci] bump extension version to ${{ steps.update.outputs.next_extension_version }} in package.json" ${{ steps.setup_branch.outputs.branch}} ${{ steps.setup_branch.outputs.new_branch }} - - - name: Trigger next workflow for Language Server tests - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 3. Test Language Server and publish - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "release_channel": "${{ env.RELEASE_CHANNEL }}", "extension_version": "${{ steps.update.outputs.next_extension_version }}", "branch": "${{steps.setup_branch.outputs.branch}}", "trigger_reason": "Prisma CLI version ${{github.event.inputs.version}}" }' diff --git a/.github/workflows/3_LS_tests_publish.yml b/.github/workflows/3_LS_tests_publish.yml deleted file mode 100644 index 61f894fa12..0000000000 --- a/.github/workflows/3_LS_tests_publish.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: 3. Test Language Server and publish -run-name: 3. Test Language Server and publish - ${{ inputs.trigger_reason }} - -on: - workflow_dispatch: - inputs: - release_channel: - description: "Identifies whether we're publishing an insider or stable release of the extension" - required: true - type: choice - options: - - insider - - stable - branch: - description: 'Branch to run run this workflow on' - required: true - extension_version: - description: 'VS Code extension version. When provided, it will trigger the next workflow to bump the LS version in the extension.' - trigger_reason: - description: 'Information about what caused the publishing process in the first place.' - -permissions: - id-token: write # required for OIDC / Trusted Publishers - -env: - PRISMA_TELEMETRY_INFORMATION: 'language-tools 3_LS_unit_tests_publish.yml' - LS_NPM_CHANNEL: ${{ github.event.inputs.release_channel == 'stable' && 'latest' || 'dev' }} - -jobs: - tests: - name: Run tests - runs-on: ${{ matrix.os }} - timeout-minutes: 10 - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - ref: ${{ github.event.inputs.branch }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Install Dependencies - run: pnpm install - - name: Build Language Server - run: pnpm --filter @prisma/language-server build - - name: Run Language Server tests - run: pnpm --filter @prisma/language-server test - - bump: - name: Bump Language Server version - needs: [tests] - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.branch }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Update npm to support Trusted Publishers - run: npm install -g npm@^11.5 - - name: Print inputs - run: | - echo ${{github.event.inputs.release_channel}} - echo ${{github.event.inputs.extension_version || 'not provided'}} - echo ${{github.event.inputs.branch}} - echo ${{github.event.inputs.trigger_reason || 'not provided'}} - - name: Install Dependencies - run: pnpm install - - name: Typecheck Language Server - run: pnpm --filter @prisma/language-server typecheck - - name: Build Language Server - run: pnpm --filter @prisma/language-server build - - name: Publish Language Server to npm - run: pnpm --filter @prisma/language-server publish --tag ${{ env.LS_NPM_CHANNEL }} --access public --no-git-checks - - name: Trigger next workflow for VS Code e2e tests - if: ${{ github.event.inputs.extension_version != '' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 4. E2E tests VS Code Extension - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "release_channel": "${{ github.event.inputs.release_channel }}", "extension_version": "${{ github.event.inputs.extension_version }}", "branch": "${{ github.event.inputs.branch }}", "trigger_reason": "${{github.event.inputs.trigger_reason}}" }' diff --git a/.github/workflows/4_e2e_tests.yml b/.github/workflows/4_e2e_tests.yml deleted file mode 100644 index d5ffa6ad47..0000000000 --- a/.github/workflows/4_e2e_tests.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: 4. E2E tests VS Code Extension -run-name: 4. E2E tests VS Code Extension - ${{ inputs.trigger_reason }} - -on: - workflow_dispatch: - inputs: - release_channel: - description: "Identifies whether we're publishing an insider or stable release of the extension" - required: true - type: choice - options: - - insider - - stable - extension_version: - description: 'VS Code extension version' - required: true - branch: - description: 'Branch to run run this workflow on' - required: true - trigger_reason: - description: 'Information about what caused the publishing process in the first place.' - required: true -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 4_e2e_tests.yml' - -jobs: - tests: - name: E2E tests VS Code Extension - runs-on: ${{ matrix.os }} - timeout-minutes: 10 - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.branch }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - cache: 'pnpm' - - name: Install Dependencies - run: pnpm install - - name: Build - run: pnpm build - - name: Headless E2E tests - uses: coactions/setup-xvfb@v1 - with: - run: pnpm test:e2e - - trigger: - name: Trigger next workflow - needs: [tests] - runs-on: ubuntu-latest - timeout-minutes: 7 - if: always() - steps: - - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Print inputs - run: | - echo ${{github.event.inputs.release_channel}} - echo ${{github.event.inputs.extension_version}} - echo ${{github.event.inputs.branch}} - echo ${{github.event.inputs.trigger_reason}} - - name: Trigger next workflow to build extension - if: ${{ needs.tests.result == 'success' }} - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 5. Build extension - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "release_channel": "${{ github.event.inputs.release_channel }}", "extension_version": "${{ github.event.inputs.extension_version }}", "branch": "${{github.event.inputs.branch}}", "trigger_reason": "${{github.event.inputs.trigger_reason}}" }' diff --git a/.github/workflows/5_build.yml b/.github/workflows/5_build.yml deleted file mode 100644 index 473b9407ef..0000000000 --- a/.github/workflows/5_build.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: 5. Build extension # and upload as release to GitHub -run-name: 5. Build extension + upload - ${{ inputs.trigger_reason }} - -on: - workflow_dispatch: - inputs: - release_channel: - description: "Identifies whether we're publishing an insider or stable release of the extension" - required: true - type: choice - options: - - insider - - stable - extension_version: - description: 'VS Code extension version' - required: true - branch: - description: 'Branch to run run this workflow on' - required: true - trigger_reason: - description: 'Information about what caused the publishing process in the first place.' - required: true - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 5_build.yml' - -jobs: - build: - name: Build extension - runs-on: ubuntu-latest - timeout-minutes: 7 - outputs: - tag_name: ${{ steps.names.outputs.tag_name }} - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.branch }} - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Print inputs - run: | - echo ${{github.event.inputs.release_channel}} - echo ${{github.event.inputs.extension_version}} - echo ${{github.event.inputs.branch}} - echo ${{github.event.inputs.trigger_reason}} - - # Build the extension - - name: Install Dependencies - run: pnpm install - - name: Typecheck all packages - run: pnpm typecheck - - name: Build all packages - run: pnpm build - - name: Replace Readme for marketplace - run: node scripts/change_readme.mjs ${{ github.event.inputs.release_channel }} - - name: Build vsix - run: cd packages/vscode && pnpm package - - # Create GitHub Release and upload built result as asset - - name: Get git tag and asset name - id: names - run: node scripts/get_tag_name.mjs ${{ github.event.inputs.release_channel }} ${{ github.event.inputs.extension_version }} - - name: create a GitHub release - id: create_release - # This action is not maintained since 3+ years! - # see https://github.com/actions/create-release/issues/119 - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.names.outputs.tag_name }} - release_name: ${{ steps.names.outputs.tag_name }} - - name: Get asset name for release asset - id: get_asset_name - run: | - echo "asset_name=${{ steps.names.outputs.asset_name }}-${{ github.event.inputs.extension_version }}.vsix" >> "$GITHUB_OUTPUT" - - - name: Upload Release Asset - id: upload-release-asset - # This action is not maintained since 3+ years! - # see https://github.com/actions/upload-release-asset/issues/78 - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{github.workspace}}/packages/vscode/${{ steps.get_asset_name.outputs.asset_name }} - asset_name: ${{ steps.get_asset_name.outputs.asset_name }} - asset_content_type: application/zip - - - name: Trigger next workflow to publish extension - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 6. Publish - token: ${{ secrets.PRISMA_BOT_TOKEN }} - inputs: '{ "asset_name": "${{ steps.get_asset_name.outputs.asset_name }}", "tag_name": "${{ steps.names.outputs.tag_name }}", "trigger_reason": "${{github.event.inputs.trigger_reason}}" }' diff --git a/.github/workflows/6_publish.yml b/.github/workflows/6_publish.yml deleted file mode 100644 index 1a72819fca..0000000000 --- a/.github/workflows/6_publish.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: 6. Publish -run-name: 6. Publish - ${{ inputs.trigger_reason }} - -on: - workflow_dispatch: - inputs: - asset_name: - description: 'Name of the .vsix file in the release' - required: true - tag_name: - description: 'The release version/tag to fetch from.' - required: true - trigger_reason: - description: 'Information about what caused the publishing process in the first place.' - required: true - -env: - ENVIRONMENT: ${{ secrets.ENVIRONMENT }} - PRISMA_TELEMETRY_INFORMATION: 'language-tools 6_publish.yml' - -jobs: - marketplace: - name: Publish to marketplace - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Print inputs - run: | - echo ${{github.event.inputs.asset_name}} - echo ${{github.event.inputs.tag_name}} - echo ${{github.event.inputs.trigger_reason}} - - name: Install Dependencies - run: pnpm install - - # Download Asset from GH release and publish to VS Code marketplace - - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: 'prisma/language-tools' - version: 'tags/${{ github.event.inputs.tag_name }}' - file: ${{ github.event.inputs.asset_name }} - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - - name: publish vsix to marketplace - run: cd packages/vscode && npx vsce publish --pat ${{ secrets.AZURE_DEVOPS_PERSONAL_ACCESS_TOKEN}} --packagePath ${{github.workspace}}/${{ github.event.inputs.asset_name }} - - open-vsx: - name: Publish to open-vsx - runs-on: ubuntu-latest - timeout-minutes: 7 - steps: - - uses: actions/checkout@v4 - - name: Install pnpm - uses: pnpm/action-setup@v4 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - name: Print inputs - run: | - echo ${{github.event.inputs.trigger_reason}} - - name: Install Dependencies - run: pnpm install - - # Download Asset from GH release and publish to open-vsx - - uses: dsaltares/fetch-gh-release-asset@master - with: - repo: 'prisma/language-tools' - version: 'tags/${{ github.event.inputs.tag_name }}' - file: ${{ github.event.inputs.asset_name }} - token: ${{ secrets.PRISMA_BOT_TOKEN }} - - - name: Publish vsix to open-vsx.org - run: cd packages/vscode && npx ovsx --debug publish ${{github.workspace}}/${{ github.event.inputs.asset_name }} --pat ${{ secrets.OPEN_VSX_ACCESS_TOKEN }} diff --git a/.github/workflows/check_for_prisma_update.yml b/.github/workflows/check_for_prisma_update.yml new file mode 100644 index 0000000000..66a94e620d --- /dev/null +++ b/.github/workflows/check_for_prisma_update.yml @@ -0,0 +1,83 @@ +name: Check for Prisma CLI update + +# Polls npm for new Prisma CLI versions and starts the Release workflow +# (release.yml) for every channel that has a new version: +# +# - dev -> insider release from main +# - latest -> stable release from the stable branch +# - patch-dev -> insider release from the x.y.x patch branch + +on: + # Scheduled trigger disabled: ORM iteration is paused; CLI-update polling + # runs on demand. Restore the `schedule:` block below to re-enable. + # schedule: + # - cron: '*/5 * * * *' + workflow_dispatch: + +env: + ENVIRONMENT: ${{ secrets.ENVIRONMENT }} + PRISMA_TELEMETRY_INFORMATION: 'language-tools check_for_prisma_update.yml' + +jobs: + check: + name: Check for Prisma CLI update + if: github.repository == 'prisma/language-tools' + runs-on: ubuntu-latest + timeout-minutes: 7 + env: + GH_TOKEN: ${{ secrets.PRISMA_BOT_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.PRISMA_BOT_TOKEN }} + fetch-depth: 0 # patch branches are created from release tags + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + + - name: Check for Prisma CLI update + id: check_update + run: node scripts/check_for_update.mjs + + - name: Record new versions + if: steps.check_update.outputs.dev_version || steps.check_update.outputs.latest_version || steps.check_update.outputs.patch-dev_version + env: + DEV_VERSION: ${{ steps.check_update.outputs.dev_version }} + LATEST_VERSION: ${{ steps.check_update.outputs.latest_version }} + PATCH_DEV_VERSION: ${{ steps.check_update.outputs.patch-dev_version }} + run: | + sh scripts/set_git_credentials.sh + if [ -n "$DEV_VERSION" ]; then echo "$DEV_VERSION" > scripts/versions/prisma_dev; fi + if [ -n "$LATEST_VERSION" ]; then echo "$LATEST_VERSION" > scripts/versions/prisma_latest; fi + if [ -n "$PATCH_DEV_VERSION" ]; then echo "$PATCH_DEV_VERSION" > scripts/versions/prisma_patch-dev; fi + git commit -am "[skip ci] record new Prisma CLI versions" + git push + + - name: Release insider (Prisma dev) + if: steps.check_update.outputs.dev_version + env: + DEV_VERSION: ${{ steps.check_update.outputs.dev_version }} + run: gh workflow run release.yml --ref main -f channel=insider -f prisma_version="$DEV_VERSION" + - name: Release stable (Prisma latest) + if: steps.check_update.outputs.latest_version + env: + LATEST_VERSION: ${{ steps.check_update.outputs.latest_version }} + run: gh workflow run release.yml --ref main -f channel=stable -f prisma_version="$LATEST_VERSION" + - name: Release insider from patch branch (Prisma patch-dev) + if: steps.check_update.outputs.patch-dev_version + env: + PATCH_DEV_VERSION: ${{ steps.check_update.outputs.patch-dev_version }} + run: | + BRANCH=$(node scripts/setup_branch.mjs patch-dev) + if [ -z "$(git ls-remote --heads origin "$BRANCH")" ]; then + # New patch branch: base it on the last marketplace-tested stable release + git branch "$BRANCH" "$(cat scripts/versions/tested_extension_stable)" + git push origin "$BRANCH" + fi + gh workflow run release.yml --ref main -f channel=insider -f ref="$BRANCH" -f prisma_version="$PATCH_DEV_VERSION" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..4cbcb11658 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,345 @@ +name: Release +run-name: "Release ${{ github.event_name == 'push' && 'insider (push to main)' || format('{0}{1}', inputs.channel, inputs.prisma_version != '' && format(' — Prisma CLI {0}', inputs.prisma_version) || '') }}" + +# The single publishing pipeline for both the insider and the stable extension. +# +# - A push to main publishes an insider release. +# - A manual dispatch publishes an insider or stable release, optionally +# bumping the Prisma CLI dependencies first (`prisma_version`), optionally +# from another branch (`ref`, e.g. an x.y.x patch branch). +# - check_for_prisma_update.yml dispatches this workflow when a new Prisma CLI +# version is published to npm. +# +# The next extension version is derived from the git release tags (`x.y.z` for +# stable, `insider/x.y.z` for insider), so a release only creates a commit when +# it actually changes dependencies (`prisma_version` given). All other jobs +# check out the exact commit resolved by the `plan` job. + +on: + push: + branches: + - main + paths-ignore: + - '.github/**' + workflow_dispatch: + inputs: + channel: + description: 'Release channel' + required: true + type: choice + options: + - insider + - stable + default: insider + ref: + description: 'Branch to release from. Defaults to main for insider and stable for stable. Use an x.y.x branch to patch an older version.' + required: false + bump: + description: "Extension version bump (stable only; 'auto' derives it from the Prisma CLI version)" + required: false + type: choice + options: + - auto + - patch + - minor + - major + default: auto + prisma_version: + description: 'Bump the Prisma CLI dependencies to this version before releasing (creates one commit on the release branch)' + required: false + +concurrency: + group: release + cancel-in-progress: false + +permissions: + contents: read + +env: + ENVIRONMENT: ${{ secrets.ENVIRONMENT }} + PRISMA_TELEMETRY_INFORMATION: 'language-tools release.yml' + NODE_VERSION: '22' + +jobs: + plan: + name: Plan release + if: github.repository == 'prisma/language-tools' + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + outputs: + channel: ${{ steps.params.outputs.channel }} + ref: ${{ steps.params.outputs.ref }} + sha: ${{ steps.sha.outputs.sha }} + version: ${{ steps.version.outputs.version }} + tag_name: ${{ steps.version.outputs.tag_name }} + asset_name: ${{ steps.version.outputs.asset_name }} + npm_channel: ${{ steps.version.outputs.npm_channel }} + ls_npm_tag: ${{ steps.version.outputs.ls_npm_tag }} + steps: + - name: Resolve channel and branch + id: params + env: + EVENT_NAME: ${{ github.event_name }} + PUSH_SHA: ${{ github.sha }} + INPUT_CHANNEL: ${{ inputs.channel }} + INPUT_REF: ${{ inputs.ref }} + run: | + if [ "$EVENT_NAME" = "push" ]; then + CHANNEL=insider + REF="$PUSH_SHA" + else + CHANNEL="$INPUT_CHANNEL" + REF="$INPUT_REF" + if [ -z "$REF" ]; then + if [ "$CHANNEL" = "stable" ]; then REF=stable; else REF=main; fi + fi + case "$REF" in + main | stable) ;; + *) + if ! echo "$REF" | grep -Eq '^[0-9]+\.[0-9]+\.x$'; then + echo "Refusing to release from '$REF'. Releases run from main, stable or an x.y.x patch branch." >&2 + exit 1 + fi + ;; + esac + fi + { + echo "channel=$CHANNEL" + echo "ref=$REF" + } >> "$GITHUB_OUTPUT" + - uses: actions/checkout@v4 + with: + ref: ${{ steps.params.outputs.ref }} + fetch-depth: 0 # all branches and tags: the next version is derived from release tags + token: ${{ secrets.PRISMA_BOT_TOKEN }} + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + - name: Compute next extension version + id: version + env: + CHANNEL: ${{ steps.params.outputs.channel }} + BUMP: ${{ inputs.bump || 'auto' }} + PRISMA_VERSION: ${{ inputs.prisma_version }} + run: node scripts/next_extension_version.mjs "$CHANNEL" "$BUMP" "$PRISMA_VERSION" + - name: Reset stable branch to main (new Prisma minor/major) + if: steps.params.outputs.channel == 'stable' && inputs.prisma_version != '' && steps.version.outputs.release_type != 'patch' + run: | + git checkout -B stable origin/main + git push --force origin stable + - name: Bump Prisma dependencies + if: inputs.prisma_version != '' + env: + NPM_CHANNEL: ${{ steps.version.outputs.npm_channel }} + VERSION: ${{ steps.version.outputs.version }} + PRISMA_VERSION: ${{ inputs.prisma_version }} + RELEASE_REF: ${{ steps.params.outputs.ref }} + run: | + node scripts/update_package_json_files.mjs "$NPM_CHANNEL" "$VERSION" "$PRISMA_VERSION" + sh scripts/set_git_credentials.sh + git commit -am "[skip ci] bump Prisma CLI to $PRISMA_VERSION and extension to $VERSION" + git push origin "HEAD:$RELEASE_REF" + - name: Resolve release commit + id: sha + run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + + test: + name: Test (${{ matrix.os }}) + needs: [plan] + runs-on: ${{ matrix.os }} + timeout-minutes: 25 + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + - name: Build all packages + run: pnpm build + - name: Typecheck all packages + run: pnpm typecheck + - name: Run Language Server tests + run: pnpm --filter @prisma/language-server test + - name: Headless E2E tests + uses: coactions/setup-xvfb@v1 + with: + run: pnpm test:e2e + + publish-language-server: + name: Publish Language Server to npm + needs: [plan, test] + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + id-token: write + env: + NPM_CHANNEL: ${{ needs.plan.outputs.npm_channel }} + VERSION: ${{ needs.plan.outputs.version }} + LS_NPM_TAG: ${{ needs.plan.outputs.ls_npm_tag }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Update npm to support Trusted Publishers + run: npm install -g npm@^11.5 + - name: Install Dependencies + run: pnpm install + - name: Set Language Server version + run: node scripts/update_package_json_files.mjs "$NPM_CHANNEL" "$VERSION" "" + - name: Build Language Server + run: pnpm --filter @prisma/language-server build + - name: Publish Language Server to npm + run: pnpm --filter @prisma/language-server publish --tag "$LS_NPM_TAG" --access public --no-git-checks + + package: + name: Build extension + needs: [plan, test] + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + CHANNEL: ${{ needs.plan.outputs.channel }} + NPM_CHANNEL: ${{ needs.plan.outputs.npm_channel }} + VERSION: ${{ needs.plan.outputs.version }} + ASSET_FILE: ${{ needs.plan.outputs.asset_name }}-${{ needs.plan.outputs.version }}.vsix + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + - name: Set extension name and version + run: node scripts/update_package_json_files.mjs "$NPM_CHANNEL" "$VERSION" "" + - name: Replace Readme for marketplace + run: node scripts/change_readme.mjs "$CHANNEL" + - name: Build all packages + run: pnpm build + - name: Build vsix + run: cd packages/vscode && pnpm package + - name: Upload vsix as workflow artifact + uses: actions/upload-artifact@v4 + with: + name: vsix + path: packages/vscode/${{ env.ASSET_FILE }} + if-no-files-found: error + + release: + name: Create GitHub release + needs: [plan, package] + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + env: + CHANNEL: ${{ needs.plan.outputs.channel }} + TAG_NAME: ${{ needs.plan.outputs.tag_name }} + ASSET_FILE: ${{ needs.plan.outputs.asset_name }}-${{ needs.plan.outputs.version }}.vsix + SHA: ${{ needs.plan.outputs.sha }} + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + steps: + - name: Download vsix artifact + uses: actions/download-artifact@v4 + with: + name: vsix + - name: Create GitHub release + run: | + PRERELEASE="" + if [ "$CHANNEL" = "insider" ]; then PRERELEASE="--prerelease"; fi + gh release create "$TAG_NAME" "$ASSET_FILE" \ + --title "$TAG_NAME" \ + --target "$SHA" \ + $PRERELEASE + + publish-marketplace: + name: Publish to VS Code Marketplace + needs: [plan, release] + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + ASSET_FILE: ${{ needs.plan.outputs.asset_name }}-${{ needs.plan.outputs.version }}.vsix + VSCE_PAT: ${{ secrets.AZURE_DEVOPS_PERSONAL_ACCESS_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + - name: Download vsix artifact + uses: actions/download-artifact@v4 + with: + name: vsix + - name: Publish vsix to marketplace + run: cd packages/vscode && npx vsce publish --packagePath "$GITHUB_WORKSPACE/$ASSET_FILE" + + publish-open-vsx: + name: Publish to open-vsx + needs: [plan, release] + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + ASSET_FILE: ${{ needs.plan.outputs.asset_name }}-${{ needs.plan.outputs.version }}.vsix + OVSX_PAT: ${{ secrets.OPEN_VSX_ACCESS_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - name: Install pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + - name: Install Dependencies + run: pnpm install + - name: Download vsix artifact + uses: actions/download-artifact@v4 + with: + name: vsix + - name: Publish vsix to open-vsx.org + run: cd packages/vscode && npx ovsx --debug publish "$GITHUB_WORKSPACE/$ASSET_FILE" diff --git a/README.md b/README.md index e1b9564c7a..bc124ffda0 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,10 @@ Press `F5` in VS Code to launch the extension in debug mode. ## Build Status -[![E2E tests before Insider release][e2e-insider-badge]][e2e-insider-action] -[![Language Server tests][ls-tests-badge]][ls-tests-action] +[![Release][release-badge]][release-action] +[![CI][ci-badge]][ci-action] -[e2e-insider-badge]: https://github.com/prisma/language-tools/workflows/5.%20Integration%20tests%20in%20VSCode%20folder%20with%20published%20LS/badge.svg?branch=main -[e2e-insider-action]: https://github.com/prisma/language-tools/actions/workflows/5_e2e_tests.yml?query=branch%3Amain -[ls-tests-badge]: https://github.com/prisma/language-tools/workflows/3.%20Unit%20tests%20for%20LS%20and%20publish/badge.svg?branch=main -[ls-tests-action]: https://github.com/prisma/language-tools/actions/workflows/3_LS_tests_publish.yml?query=branch%3Amain +[release-badge]: https://github.com/prisma/language-tools/actions/workflows/release.yml/badge.svg?branch=main +[release-action]: https://github.com/prisma/language-tools/actions/workflows/release.yml?query=branch%3Amain +[ci-badge]: https://github.com/prisma/language-tools/actions/workflows/continuous-integration.yml/badge.svg?branch=main +[ci-action]: https://github.com/prisma/language-tools/actions/workflows/continuous-integration.yml?query=branch%3Amain diff --git a/docs/architecture.md b/docs/architecture.md index 55822ad18d..a0dd696b33 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -69,9 +69,10 @@ assets (`pglite.data`, `pglite.wasm`) are copied separately ⁴ Kept separate to support runtime switching between Prisma 6 and latest language servers via the `prisma.pinToPrisma6` setting -> **Note:** These dependencies are automatically updated via CI. A cron job -> runs every 5 minutes checking for new Prisma releases -> (see `.github/workflows/1_check_for_updates.yml`). +> **Note:** These dependencies are updated via CI by +> `.github/workflows/check_for_prisma_update.yml`, which checks npm for new +> Prisma CLI releases and dispatches `release.yml`. Its cron schedule is +> currently disabled; dispatch it manually. See [CI/CD](ci-cd.md). ## File Organization diff --git a/docs/ci-cd.md b/docs/ci-cd.md index f673494e7c..2af4cd9184 100644 --- a/docs/ci-cd.md +++ b/docs/ci-cd.md @@ -1,36 +1,99 @@ # CI/CD Overview -The repository has extensive GitHub Actions workflows: - -| Workflow | Trigger | Purpose | -| ------------------------- | ------------------ | ------------------------------ | -| `1_check_for_updates.yml` | Every 5 min (cron) | Checks for new Prisma releases | -| `2_bump_versions.yml` | Triggered by #1 | Bumps Prisma dependencies | -| `3_LS_tests_publish.yml` | On version bump | Tests and publishes LS to npm | -| `4_e2e_tests.yml` | Before releases | Runs E2E tests | -| `5_build.yml` | After E2E pass | Builds extension | -| `6_publish.yml` | After build | Publishes VS Code extension | -| `PR_build_extension.yml` | On PRs | Builds `.vsix` for testing | +## Publishing pipeline + +All publishing — insider **and** stable — happens in a single workflow: +[`release.yml`](../.github/workflows/release.yml). There are no chained +workflows and no version-bump commits: the next extension version is derived +from the git release tags (`x.y.z` for stable, `insider/x.y.z` for insider, +one shared monotonic counter). The only commit a release can create is a real +dependency bump when a new Prisma CLI version is passed in. + +### Triggers + +| Trigger | Result | +| ---------------------------------------------- | ------------------------------------------------------------------------- | +| Push to `main` | Insider release | +| Manual `workflow_dispatch` | Insider or stable release, optional Prisma CLI bump, optional branch | +| `check_for_prisma_update.yml` (cron, disabled) | Dispatches `release.yml` when a new Prisma CLI version is released on npm | + +### Jobs ```mermaid graph TD - A(Cron every 5 minutes) --> B[1. Check for Prisma CLI Update] - B -->|update available?| C[2. Bump versions] - C -->D{Which NPM channel was updated?} - D -->|dev or patch-dev| E((Our release_channel is insider)) - D -->|latest| F((Our release_channel is stable)) - E --> G[3. Test Language Server and publish] - F --> G - G -->|tests and publish successful?| I[4. E2E tests VS Code Extension] - I -->|tests pass?| J[5. Build extension] - J --> K[6. Publish] - - L(Commit in the extension) --> M[1/2. Bump versions for extension only] - M -->E - N(Manual workflow dispatch) --> O[1/2. Bump and release a stable version of the extension] - O -->F + PUSH(Push to main) --> PLAN + MANUAL(Manual dispatch: channel, bump, prisma_version) --> PLAN + CRON(check_for_prisma_update.yml cron) --> PLAN + + subgraph release.yml + PLAN[plan: resolve channel + branch, derive next version from git tags,
optionally commit Prisma CLI dependency bump] + PLAN --> TEST[test: build, typecheck, LS unit tests, E2E tests
on ubuntu / macos / windows] + TEST --> LS[publish-language-server:
npm publish with dist-tag dev or latest] + TEST --> PKG[package: build vsix, upload artifact] + PKG --> REL[release: download artifact,
create GitHub release + tag] + REL --> MKT[publish-marketplace: vsce publish] + REL --> OVSX[publish-open-vsx: ovsx publish] + end ``` +- **plan** resolves the release channel (`insider`/`stable`), the branch, and + the next version, and outputs a single commit SHA that every later job + checks out — no state is passed through commits mid-pipeline. +- **test** gates publishing: build, typecheck, Language Server unit tests and + VS Code E2E tests on all three OSes. +- **package** builds the `.vsix` once; the same file is attached to the GitHub + release and published to both marketplaces (passed as a workflow artifact). +- **release** only downloads that artifact and creates the tag and GitHub + release. It does not check out, install or build anything. +- Insider GitHub releases are marked as pre-releases, so the repository's + "latest release" always points to a stable version. + +### Permissions + +The workflow default is `contents: read`. Write access is granted per job: +`plan` (pushes the dependency-bump commit and can reset `stable`), `release` +(creates the tag and GitHub release) and `publish-language-server` +(`id-token: write` for npm Trusted Publishers). Every checkout except `plan`'s +sets `persist-credentials: false`, so build and test steps never see a git +credential. + +Releases only run from `main`, `stable` or an `x.y.x` patch branch; `plan` +rejects any other `ref`. + +### Channels and branches + +| Channel | Branch | Extension name | LS npm dist-tag | +| ------- | --------------- | ---------------- | --------------- | +| insider | `main` | `prisma-insider` | `dev` | +| stable | `stable` | `prisma` | `latest` | +| insider | `x.y.x` patches | `prisma-insider` | `dev` | + +The `stable` branch pins the Prisma CLI `latest` dependencies while `main` +tracks `dev`. When a stable release ships a new Prisma minor or major, the +`plan` job resets `stable` to `main`. Patch releases for older versions are +made by dispatching `release.yml` with an `x.y.x` branch as `ref` +(channel `insider` for a `patch-dev` CLI, `stable` for the final patch). + +### Prisma CLI update automation + +[`check_for_prisma_update.yml`](../.github/workflows/check_for_prisma_update.yml) +(cron, currently disabled — dispatch manually) compares the npm versions of +`prisma@dev`, `prisma@latest` and `prisma@patch-dev` against +`scripts/versions/prisma_*`, records new versions there, and dispatches +`release.yml` for each channel that changed. + +## Other workflows + +| Workflow | Trigger | Purpose | +| -------------------------------------- | ------------------- | -------------------------------------------- | +| `continuous-integration.yml` | PRs, push to main | Tests, lint, typecheck, Playwright | +| `PR_build_extension.yml` | PRs | Builds a `.vsix` artifact for manual testing | +| `e2e_check_for_new_published_vsix.yml` | Cron (disabled) | Detects new marketplace releases | +| `e2e_published_vsix.yml` | Dispatched by above | E2E tests against the published extension | +| `codeql-analysis.yml` | PRs, push, cron | CodeQL security analysis | +| `pr-code-security.yml` | PRs | Security checks | +| `update-api-types.yml` | Cron / manual | Updates generated API types | + ## Testing PR Builds When you open a PR, the `PR_build_extension.yml` workflow automatically builds a diff --git a/packages/vscode/CONTRIBUTING.md b/packages/vscode/CONTRIBUTING.md index 3a376e2dfd..59289474d1 100644 --- a/packages/vscode/CONTRIBUTING.md +++ b/packages/vscode/CONTRIBUTING.md @@ -94,16 +94,16 @@ For releases that don't coincide with a Prisma ORM release: **Insider release:** -- Push to `main` or a patch branch (e.g., `35.0.x`) -- Automatically triggers [`1/2. Bump versions for extension only`][bump-workflow] +- Push to `main`, which triggers [`Release`][release-workflow] +- For a patch branch (e.g. `35.0.x`), dispatch [`Release`][release-workflow] + with channel `insider` and that branch as `ref` **Stable release:** -- Manually trigger [`1/2. Bump and release a stable version`][stable-workflow] -- Select release type: `patch`, `minor`, or `major` +- Manually dispatch [`Release`][release-workflow] with channel `stable` +- Select the bump: `auto`, `patch`, `minor` or `major` -[bump-workflow]: ../../.github/workflows/1_2_bump_extension_only.yml -[stable-workflow]: ../../.github/workflows/1_2_stable_extension_release.yml +[release-workflow]: ../../.github/workflows/release.yml ## Dependencies diff --git a/scripts/__tests__/__snapshots__/change-readme.test.js.snap b/scripts/__tests__/__snapshots__/change-readme.test.js.snap deleted file mode 100644 index a711740514..0000000000 --- a/scripts/__tests__/__snapshots__/change-readme.test.js.snap +++ /dev/null @@ -1,207 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`changeReadme it should with an insider release 1`] = ` -"

Prisma VS Code Extension - Insider

- -## Insider Build - -This is the Insider Build of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma). Most users should not use this version, but instead install -the regular version of the extension.This version of the extension may contain unstable prerelease code and is directly built from the main branch. - -**Only use this extension if you are also using the dev version of the CLI.** - -Please note that you should not have the regular and insider version of the extension installed at the same time. - -## Preview - -
- Syntax-Highlighting - -Syntax highlighting eases visual comprehension of the Prisma schema. -![Preview Schema](https://user-images.githubusercontent.com/1328733/147264843-fc32c2aa-7490-4e49-9478-abc16cbd0682.png) - -
-
- Formatting - -Formatting ensures consistent indentation of your models for better readability. -![Formatting](https://user-images.githubusercontent.com/1328733/147264852-849cb539-9bdc-4916-9d0f-483536061f7c.gif) - -
-
- Linting and autocompletion - -Linting shows inline errors in the schema, and autocompletion assists in defining the correct type. -![Linting and autocompletion](https://user-images.githubusercontent.com/1328733/147265321-2e1956ec-9f57-4ff3-9493-8163a727308d.gif) - -
-
- Contextual suggestions - -Contextual suggestions assist in defining field types, models, and relations while formatting automatically defines back relations. -![Contextual suggestions](https://user-images.githubusercontent.com/1328733/147265323-4eb397b4-acda-4c78-9f27-1230d7ea4603.gif) - -
-
- Jump-to-definition - -Easily navigate definitions, i.e. models in the Prisma schema. - -![Jump-to-definition](https://user-images.githubusercontent.com/1328733/147265315-838cd63c-e0c6-485c-aec9-1b1707291719.gif) - -
- -## Build information - -- This version is built from commit [undefined](https://github.com/prisma/language-tools/commit/undefined). -- This is for Prisma CLI 2.5.0-dev.4. - -## Contributing - -Read more about [how to contribute to the Prisma VS Code extension](./packages/vscode/CONTRIBUTING.md) - -## Telemetry - -This extension collects telemetry data to help us better the usage of the extension. You can read more about that [here](https://www.prisma.io/docs/reference/more/telemetry). -The extension respects: - -- the \`telemetry.enableTelemetry\` setting in VS Code ([deprecated since v1.61](https://code.visualstudio.com/updates/v1_61#_telemetry-settings)). -- the \`telemetry.telemetryLevel\` setting in VS Code (see [docs](https://code.visualstudio.com/docs/getstarted/telemetry)) - -If you want to opt out of telemetry you can either, in your VS Code settings: - -- set \`"telemetry.enableTelemetry": false\` -- set \`"telemetry.telemetryLevel": "off"\` (or "crash" or "error") - -## Security - -If you have a security issue to report, please contact us at [security@prisma.io](mailto:security@prisma.io?subject=[GitHub]%20Prisma%202%20Security%20Report%20VSCode) -" -`; - -exports[`changeReadme it should work with a stable release 1`] = ` -"

Prisma VS Code Extension

-
- Adds a database management UI, syntax highlighting, linting, code completion, formatting, jump-to-definition and more. -
- -## Features - -### Visual database management UI - -The Prisma VS Code extension features a database managent UI that you can access via the **Prisma logo** in the sidebar. It allows to manage Prisma Postgres instances: - -- Authenticate with the [Prisma Console](https://console.prisma.io) -- Create and delete Prisma Postgres instances (remote & local) -- View and edit data via an embedded Prisma Studio -- Visualize your database schema - -### Editor support - -- Syntax highlighting of \`schema.prisma\` -- Linting - - Diagnostic tools are used to surface errors and warnings in your schema file as you type. -- Code Completion - - Completion results appear for symbols as you type. - - You can trigger this manually with the \`Ctrl+Space\` shortcut. -- Documentation help - - Documentation of a completion result pops up as completion results are provided. -- Quick info on hover - - Documentation Comments (\`///\`) of models and enums appear anywhere you hover over their usages. -- Go to Definition - - Jump to or peek a model or enum's declaration. -- Formatting - - Format code either manually or on save (if configured). - - _To automatically format on save, add the following to your \`settings.json\` file:_ - \`\`\` - "editor.formatOnSave": true - \`\`\` - - _To enable formatting in combination with \`prettier\`, add the following to your \`settings.json\` file:_ - \`\`\` - "[prisma]": { - "editor.defaultFormatter": "Prisma.prisma" - }, - \`\`\` - or use the [Prettier plugin for Prisma](https://github.com/umidbekk/prettier-plugin-prisma) -- Rename - - Rename models, enums, fields and enum values - - Click into the model or enum, press \`F2\` and then type the new desired name and press \`Enter\` - - All usages will be renamed - - Automatically applies \`@map\` or \`@@map\` on the schema -- Quick-fixes - - Quickly fix typos in model and enum names - - Create new models and enums with a single click - -## Preview - -
- Database management UI - -The database management UI gives you a visual way to perform various database workflows. -![Preview Schema](https://cdn.sanity.io/images/p2zxqf70/production/f7a4f862f7f12d96c98eafef1b6bf0f2d0cac943-3740x1964.png) - -
- -
- Syntax highlighting - -Syntax highlighting eases visual comprehension of the Prisma schema. -![Preview Schema](https://user-images.githubusercontent.com/1328733/147264843-fc32c2aa-7490-4e49-9478-abc16cbd0682.png) - -
-
- Formatting - -Formatting ensures consistent indentation of your models for better readability. -![Formatting](https://user-images.githubusercontent.com/1328733/147264852-849cb539-9bdc-4916-9d0f-483536061f7c.gif) - -
-
- Linting and autocompletion - -Linting shows inline errors in the schema, and autocompletion assists in defining the correct type. -![Linting and autocompletion](https://user-images.githubusercontent.com/1328733/147265321-2e1956ec-9f57-4ff3-9493-8163a727308d.gif) - -
-
- Contextual suggestions - -Contextual suggestions assist in defining field types, models, and relations while formatting automatically defines back relations. -![Contextual suggestions](https://user-images.githubusercontent.com/1328733/147265323-4eb397b4-acda-4c78-9f27-1230d7ea4603.gif) - -
-
- Jump-to-definition - -Easily navigate definitions, i.e. models in the Prisma schema. - -![Jump-to-definition](https://user-images.githubusercontent.com/1328733/147265315-838cd63c-e0c6-485c-aec9-1b1707291719.gif) - -
- -## Contributing - -Read more about [how to contribute to the Prisma VS Code extension](./packages/vscode/CONTRIBUTING.md) - -## Telemetry - -This extension collects telemetry data to help us better the usage of the extension. You can read more about that [in Prisma's documentation](https://www.prisma.io/docs/reference/more/telemetry). -The extension respects: - -- the \`telemetry.enableTelemetry\` setting in VS Code ([deprecated since v1.61](https://code.visualstudio.com/updates/v1_61#_telemetry-settings)). -- the \`telemetry.telemetryLevel\` setting in VS Code (see [docs](https://code.visualstudio.com/docs/getstarted/telemetry)) - -If you want to opt out of telemetry you can either, in your VS Code settings: - -- set \`"telemetry.enableTelemetry": false\` -- set \`"telemetry.telemetryLevel": "off"\` (or "crash" or "error") - -## Build information - -This is for Prisma CLI 2.4.0. - -## Security - -If you have a security issue to report, please contact us at [security@prisma.io](mailto:security@prisma.io?subject=[GitHub]%20Prisma%202%20Security%20Report%20VSCode) -" -`; diff --git a/scripts/__tests__/change-readme.test.js b/scripts/__tests__/change-readme.test.js deleted file mode 100644 index f406e78301..0000000000 --- a/scripts/__tests__/change-readme.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { describe, it, expect } from 'vitest' -import { getNewReadMeContent } from '../change_readme.mjs' - -describe('changeReadme', () => { - - it('it should with an insider release', () => { - expect( - getNewReadMeContent({ - releaseChannel: 'insider', - cliVersion: '2.5.0-dev.4', - }), - ).toMatchSnapshot() - }) - - it('it should work with a stable release', () => { - expect( - getNewReadMeContent({ - releaseChannel: 'stable', - cliVersion: '2.4.0', - }), - ).toMatchSnapshot() - }) -}) diff --git a/scripts/__tests__/dependencies.test.js b/scripts/__tests__/dependencies.test.js deleted file mode 100644 index d9c08375a8..0000000000 --- a/scripts/__tests__/dependencies.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, it, expect } from 'vitest' -import semver from 'semver' -import { createRequire } from 'module' -import { fileURLToPath } from 'url' -import { dirname } from 'path' - -const __filename = fileURLToPath(import.meta.url) -const __dirname = dirname(__filename) -const require = createRequire(import.meta.url) - -describe('version incompatibilities', () => { - it('@types/vscode should be less than or equal to engine.vscode version', () => { - const packageJson = require('../../packages/vscode/package.json') - const vscodeTypes = packageJson.devDependencies['@types/vscode'] - const vscodeEngine = packageJson.engines.vscode - expect( - semver.ltr(vscodeTypes, vscodeEngine) || - semver.eq(vscodeTypes, vscodeEngine.substring(1)), - ).toBeTruthy() - }) -}) diff --git a/scripts/__tests__/extension-version.test.js b/scripts/__tests__/extension-version.test.js deleted file mode 100644 index 0d2337e1c2..0000000000 --- a/scripts/__tests__/extension-version.test.js +++ /dev/null @@ -1,93 +0,0 @@ -import { describe, it, expect, beforeAll } from 'vitest' -import { nextVersion } from '../bump_extension_version.mjs' - -describe('next extension version', () => { - // - // normal insider release - // - it('insider release triggered by Prisma CLI', () => { - expect( - nextVersion({ - currentVersion: '35.0.1', - trigger: 'prisma-dev-release', - prismaLatest: '2.4.0', - }), - ).toEqual('35.0.2') - }) - - it('insider release triggered by Prisma CLI after an extension only release', () => { - expect( - nextVersion({ - currentVersion: '35.0.2', - trigger: 'prisma-dev-release', - prismaLatest: '2.4.0', - }), - ).toEqual('35.0.3') - }) - - it('a first Prisma CLI patch on stable', () => { - expect( - nextVersion({ - currentVersion: '32.5.0', - trigger: 'prisma-latest-release', - prismaLatest: '2.5.1', - }), - ).toEqual('32.5.1') - }) - - it('a Prisma CLI patch on stable', () => { - expect( - nextVersion({ - currentVersion: '32.5.1', - trigger: 'prisma-latest-release', - prismaLatest: '2.5.1', - }), - ).toEqual('32.5.2') - }) - - // - // extension version bumps - // - it('patch version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-patch-release', - prismaLatest: '2.5.0', - }), - ).toEqual('35.1.4') - }) - - it('minor version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-minor-release', - prismaLatest: '2.5.0', - }), - ).toEqual('35.2.0') - }) - - it('major version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-major-release', - prismaLatest: '2.5.0', - }), - ).toEqual('36.0.0') - }) - - // - // first extension release after Prisma CLI major update - // - it('first extension release after a major Prisma CLI update (4.0.0)', () => { - expect( - nextVersion({ - currentVersion: '32.15.9', - trigger: 'prisma-latest-release', - prismaLatest: '4.0.0', - }), - ).toEqual('33.0.0') - }) -}) diff --git a/scripts/__tests__/extension-version.test.mjs b/scripts/__tests__/extension-version.test.mjs deleted file mode 100644 index d46635390b..0000000000 --- a/scripts/__tests__/extension-version.test.mjs +++ /dev/null @@ -1,93 +0,0 @@ -import { describe, it, expect } from 'vitest' -import { nextVersion } from '../bump_extension_version.mjs' - -describe('next extension version', () => { - // - // normal insider release - // - it('insider release triggered by Prisma CLI', () => { - expect( - nextVersion({ - currentVersion: '35.0.1', - trigger: 'prisma-dev-release', - prismaLatest: '2.4.0', - }), - ).toEqual('35.0.2') - }) - - it('insider release triggered by Prisma CLI after an extension only release', () => { - expect( - nextVersion({ - currentVersion: '35.0.2', - trigger: 'prisma-dev-release', - prismaLatest: '2.4.0', - }), - ).toEqual('35.0.3') - }) - - it('a first Prisma CLI patch on stable', () => { - expect( - nextVersion({ - currentVersion: '32.5.0', - trigger: 'prisma-latest-release', - prismaLatest: '2.5.1', - }), - ).toEqual('32.5.1') - }) - - it('a Prisma CLI patch on stable', () => { - expect( - nextVersion({ - currentVersion: '32.5.1', - trigger: 'prisma-latest-release', - prismaLatest: '2.5.1', - }), - ).toEqual('32.5.2') - }) - - // - // extension version bumps - // - it('patch version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-patch-release', - prismaLatest: '2.5.0', - }), - ).toEqual('35.1.4') - }) - - it('minor version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-minor-release', - prismaLatest: '2.5.0', - }), - ).toEqual('35.2.0') - }) - - it('major version bump', () => { - expect( - nextVersion({ - currentVersion: '35.1.3', - trigger: 'extension-major-release', - prismaLatest: '2.5.0', - }), - ).toEqual('36.0.0') - }) - - // - // first extension release after Prisma CLI major update - // - it('first extension release after a major Prisma CLI update (4.0.0)', () => { - expect( - nextVersion({ - currentVersion: '32.15.9', - trigger: 'prisma-latest-release', - prismaLatest: '4.0.0', - }), - ).toEqual('33.0.0') - }) -}) diff --git a/scripts/__tests__/next-extension-version.test.mjs b/scripts/__tests__/next-extension-version.test.mjs new file mode 100644 index 0000000000..04395060b6 --- /dev/null +++ b/scripts/__tests__/next-extension-version.test.mjs @@ -0,0 +1,102 @@ +import { describe, it, expect } from 'vitest' +import { latestReleasedVersion, releaseType, planRelease } from '../next_extension_version.mjs' + +const TAGS = [ + '31.11.0', + '31.12.0', + 'insider/31.10.5', + 'insider/31.11.1', + '@prisma/language-server@0.0.1307', + 'prisma-vscode@0.0.45', + '', +] + +describe('latestReleasedVersion', () => { + it('picks the highest version across stable and insider tags', () => { + expect(latestReleasedVersion({ tags: TAGS })).toEqual('31.12.0') + }) + + it('picks an insider tag when it is the highest', () => { + expect(latestReleasedVersion({ tags: ['31.12.0', 'insider/31.12.1'] })).toEqual('31.12.1') + }) + + it('throws when there are no release tags', () => { + expect(() => latestReleasedVersion({ tags: ['prisma-vscode@0.0.45'] })).toThrow() + }) +}) + +describe('releaseType', () => { + it('insider releases are always a patch', () => { + expect(releaseType({ channel: 'insider', bump: 'auto', prismaVersion: '7.9.0-dev.4' })).toEqual('patch') + }) + + it('stable release for a Prisma CLI patch', () => { + expect(releaseType({ channel: 'stable', bump: 'auto', prismaVersion: '7.8.1' })).toEqual('patch') + }) + + it('stable release for a Prisma CLI minor', () => { + expect(releaseType({ channel: 'stable', bump: 'auto', prismaVersion: '7.9.0' })).toEqual('minor') + }) + + it('stable release for a Prisma CLI major', () => { + expect(releaseType({ channel: 'stable', bump: 'auto', prismaVersion: '8.0.0' })).toEqual('major') + }) + + it('stable extension-only release defaults to a patch', () => { + expect(releaseType({ channel: 'stable', bump: 'auto' })).toEqual('patch') + }) + + it('an explicit bump wins over the Prisma CLI version', () => { + expect(releaseType({ channel: 'stable', bump: 'minor', prismaVersion: '7.8.1' })).toEqual('minor') + }) + + it('throws on an unknown channel', () => { + expect(() => releaseType({ channel: 'nightly' })).toThrow() + }) + + it('throws on an unknown bump', () => { + expect(() => releaseType({ channel: 'stable', bump: 'mega' })).toThrow() + }) + + it('throws on a Prisma CLI version that is not a semantic version', () => { + expect(() => releaseType({ channel: 'stable', bump: 'auto', prismaVersion: 'invalid.0.0' })).toThrow( + /Invalid Prisma CLI version/, + ) + }) + + it('throws on a Prisma CLI prerelease for a stable release', () => { + expect(() => releaseType({ channel: 'stable', bump: 'auto', prismaVersion: '7.9.0-dev.4' })).toThrow(/prerelease/) + }) + + it('validates the Prisma CLI version even when the bump is explicit', () => { + expect(() => releaseType({ channel: 'stable', bump: 'minor', prismaVersion: 'invalid.0.0' })).toThrow() + }) + + it('does not validate the Prisma CLI version on the insider channel', () => { + expect(releaseType({ channel: 'insider', bump: 'auto', prismaVersion: 'anything' })).toEqual('patch') + }) +}) + +describe('planRelease', () => { + it('plans an insider release', () => { + expect(planRelease({ channel: 'insider', bump: 'auto', prismaVersion: '7.9.0-dev.4', tags: TAGS })).toEqual({ + version: '31.12.1', + release_type: 'patch', + tag_name: 'insider/31.12.1', + asset_name: 'prisma-insider', + ls_npm_tag: 'dev', + npm_channel: 'dev', + }) + }) + + it('plans a stable release for a Prisma CLI minor', () => { + expect(planRelease({ channel: 'stable', bump: 'auto', prismaVersion: '7.9.0', tags: TAGS })).toEqual({ + version: '31.13.0', + release_type: 'minor', + tag_name: '31.13.0', + asset_name: 'prisma', + ls_npm_tag: 'latest', + npm_channel: 'latest', + }) + }) +}) diff --git a/scripts/bump_extension_version.mjs b/scripts/bump_extension_version.mjs deleted file mode 100644 index fcccc0e154..0000000000 --- a/scripts/bump_extension_version.mjs +++ /dev/null @@ -1,77 +0,0 @@ -import semVer from 'semver' -import core from '@actions/core' -import { fileURLToPath } from 'url' -import { argv } from 'process' -import { readVersionFile, writeToVersionFile } from './util.mjs' - -export function nextVersion({ currentVersion, trigger, prismaLatest }) { - switch (trigger) { - case 'extension-patch-release': - case 'prisma-dev-release': - case 'prisma-patch-dev-release': - return semVer.inc(currentVersion, 'patch') - case 'extension-minor-release': - return semVer.inc(currentVersion, 'minor') - case 'extension-major-release': - return semVer.inc(currentVersion, 'major') - case 'prisma-latest-release': - // Stable release trigger bumps according to Prisma CLI version change - if (isMajorRelease(prismaLatest)) { - return semVer.inc(currentVersion, 'major') - } else if (isMinorRelease(prismaLatest)) { - return semVer.inc(currentVersion, 'minor') - } else { - return semVer.inc(currentVersion, 'patch') - } - default: - throw new Error( - 'This function needs to be called with a known trigger: extension-(patch|minor|major)-release or prisma-(latest|dev|patch-dev)-release.', - ) - } -} - -export function currentExtensionVersion() { - return readVersionFile({ fileName: 'extension_latest' }) -} - -export function bumpExtensionVersionInScriptFiles({ nextVersion: nextVersionValue }) { - writeToVersionFile({ fileName: 'extension_latest', content: nextVersionValue }) -} - -function isMinorRelease(prismaVersion) { - const [, minor, patch] = prismaVersion.split('.') - return minor !== '0' && patch === '0' -} - -function isMajorRelease(prismaVersion) { - const [, minor, patch] = prismaVersion.split('.') - return minor === '0' && patch === '0' -} - -export function isMinorOrMajorRelease(prismaVersion) { - return isMinorRelease(prismaVersion) || isMajorRelease(prismaVersion) -} - -// Only run top-level code if this file is being executed directly (not imported) -if (fileURLToPath(import.meta.url) === argv[1]) { - const args = process.argv.slice(2) - const trigger = args[0] - - // Get the current extension version - const currentVersionOfExtension = currentExtensionVersion() - console.log(`Current extension version: ${currentVersionOfExtension}`) - - // "Calculate" next version number - const version = nextVersion({ - currentVersion: currentVersionOfExtension, - trigger, - prismaLatest: readVersionFile({ fileName: 'prisma_latest' }), - }) - console.log(`Next extension version ${version}.`) - core.setOutput('next_extension_version', version) - - // Bump in file - bumpExtensionVersionInScriptFiles({ nextVersion: version }) - console.log(`Bumped extension version in scripts/version folder.`) -} - diff --git a/scripts/commit_and_push.sh b/scripts/commit_and_push.sh deleted file mode 100644 index edcd8a7705..0000000000 --- a/scripts/commit_and_push.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -# shellcheck disable=SC2086 - -set -eu - -# For local development, in production, the environment will be set though GH actions and GH secrets -if [ -f ".envrc" ]; then - echo "Loading .envrc" - # shellcheck disable=SC1091 - . .envrc -else - echo "No .envrc" -fi - -COMMIT_MESSAGE=$1 -echo "COMMIT_MESSAGE: $COMMIT_MESSAGE" - -BRANCH=${2-main} -echo "BRANCH: $BRANCH" - -NEW_BRANCH=${3-false} -echo "NEW BRANCH: $NEW_BRANCH" - -git add -A . -git commit -am "$COMMIT_MESSAGE" - -if [ "$NEW_BRANCH" = "false" ]; then - git pull --rebase - git push -else - ## Do not rebase on newly created branch - git push --set-upstream origin $BRANCH -fi diff --git a/scripts/get_tag_name.mjs b/scripts/get_tag_name.mjs deleted file mode 100644 index c2bcc0d175..0000000000 --- a/scripts/get_tag_name.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import core from '@actions/core' - -const args = process.argv.slice(2) -const releaseChannel = args[0] -const vscodeVersion = args[1] - -if (releaseChannel === 'stable') { - core.setOutput('tag_name', vscodeVersion) - core.setOutput('asset_name', 'prisma') -} else { - core.setOutput('tag_name', `insider/${vscodeVersion}`) - core.setOutput('asset_name', 'prisma-insider') -} - diff --git a/scripts/is_minor_or_major_release.mjs b/scripts/is_minor_or_major_release.mjs deleted file mode 100644 index 5b2650c886..0000000000 --- a/scripts/is_minor_or_major_release.mjs +++ /dev/null @@ -1,12 +0,0 @@ -import core from '@actions/core' -import { isMinorOrMajorRelease } from './bump_extension_version.mjs' -import { readVersionFile } from './util.mjs' - -const args = process.argv.slice(2) -const releaseChannel = args[0] -if (releaseChannel === 'latest') { - const prisma_latest = readVersionFile({ fileName: 'prisma_latest' }) - const isMinorOrMajor = isMinorOrMajorRelease(prisma_latest) - core.setOutput('is_minor_or_major_release', isMinorOrMajor) -} - diff --git a/scripts/next_extension_version.mjs b/scripts/next_extension_version.mjs new file mode 100644 index 0000000000..0284f31234 --- /dev/null +++ b/scripts/next_extension_version.mjs @@ -0,0 +1,95 @@ +import semVer from 'semver' +import core from '@actions/core' +import { execSync } from 'child_process' +import { fileURLToPath } from 'url' +import { argv } from 'process' + +const BUMPS = ['auto', 'patch', 'minor', 'major'] + +// The extension version is a single monotonic counter shared by both channels. +// It is derived from the release tags (`x.y.z` for stable, `insider/x.y.z` for +// insider) instead of a committed version file, so releasing does not require +// any bot commits. +export function latestReleasedVersion({ tags }) { + const versions = tags + .map((tag) => tag.replace(/^insider\//, '')) + .filter((tag) => semVer.valid(tag)) + .sort(semVer.rcompare) + + if (versions.length === 0) { + throw new Error('Could not find any release tags (`x.y.z` or `insider/x.y.z`) to derive the next version from.') + } + return versions[0] +} + +function parseStablePrismaVersion(prismaVersion) { + const parsed = semVer.parse(prismaVersion) + if (parsed === null) { + throw new Error(`Invalid Prisma CLI version '${prismaVersion}'. Expected a semantic version such as 7.9.0.`) + } + if (parsed.prerelease.length > 0) { + throw new Error( + `Prisma CLI version '${prismaVersion}' is a prerelease and can not be released on the stable channel.`, + ) + } + return parsed +} + +export function releaseType({ channel, bump = 'auto', prismaVersion = '' }) { + if (channel === 'insider') { + return 'patch' + } + if (channel !== 'stable') { + throw new Error(`Unknown release channel '${channel}'. Expected 'insider' or 'stable'.`) + } + if (!BUMPS.includes(bump)) { + throw new Error(`Unknown bump '${bump}'. Expected one of: ${BUMPS.join(', ')}.`) + } + + const prisma = prismaVersion === '' ? null : parseStablePrismaVersion(prismaVersion) + + if (bump !== 'auto') { + return bump + } + // 'auto' on stable mirrors the Prisma CLI release this extension ships: + // x.0.0 -> major, x.y.0 -> minor, everything else (or no CLI bump) -> patch + if (prisma !== null) { + if (prisma.minor === 0 && prisma.patch === 0) { + return 'major' + } + if (prisma.patch === 0) { + return 'minor' + } + } + return 'patch' +} + +export function planRelease({ channel, bump, prismaVersion, tags }) { + const currentVersion = latestReleasedVersion({ tags }) + const type = releaseType({ channel, bump, prismaVersion }) + const version = semVer.inc(currentVersion, type) + const stable = channel === 'stable' + + return { + version, + release_type: type, + tag_name: stable ? version : `insider/${version}`, + asset_name: stable ? 'prisma' : 'prisma-insider', + // npm dist-tag for @prisma/language-server + ls_npm_tag: stable ? 'latest' : 'dev', + // channel name understood by update_package_json_files.mjs + npm_channel: stable ? 'latest' : 'dev', + } +} + +// Only run top-level code if this file is being executed directly (not imported) +if (fileURLToPath(import.meta.url) === argv[1]) { + const [channel, bump = 'auto', prismaVersion = ''] = process.argv.slice(2) + const tags = execSync('git tag --list', { encoding: 'utf-8' }).split('\n') + + const plan = planRelease({ channel, bump, prismaVersion, tags }) + console.log(plan) + for (const [key, value] of Object.entries(plan)) { + core.setOutput(key, value) + } +} diff --git a/scripts/setup_branch.sh b/scripts/setup_branch.sh deleted file mode 100644 index 04b0ca34cf..0000000000 --- a/scripts/setup_branch.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh - -set -eu - -# For local development, in production, the environment will be set though GH actions and GH secrets -if [ -f ".envrc" ]; then - echo "Loading .envrc" - # shellcheck disable=SC1091 - . .envrc -else - echo "No .envrc" -fi - -NPM_CHANNEL=$1 - -if [ "$NPM_CHANNEL" = "dev" ]; then - echo "Not switching branch because we are on NPM_CHANNEL dev." - echo "branch=main" >> "$GITHUB_OUTPUT" -elif [ "$NPM_CHANNEL" = "promote_patch-dev" ]; then - PATCH_BRANCH=$(node scripts/setup_branch.mjs "patch-dev") - git checkout -f stable - git reset --hard "$PATCH_BRANCH" # Reset stable to patch-dev branch - git push -f # do not merge, only use state of PATCH_BRANCH - echo "branch=main" >> "$GITHUB_OUTPUT" -else - BRANCH=$(node scripts/setup_branch.mjs "$NPM_CHANNEL") - echo "BRANCH: $BRANCH" - - git fetch - - EXISTS_ALREADY=$(git ls-remote --heads origin "$BRANCH") - echo "$EXISTS_ALREADY" - - if [ "${EXISTS_ALREADY}" = "" ]; then - echo "Branch $BRANCH does not exist yet." - echo "new_branch=true" >> "$GITHUB_OUTPUT" - echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" - - if [ "$ENVIRONMENT" = "PRODUCTION" ]; then - git config --global user.email "prismabots@gmail.com" - git config --global user.name "Prismo" - - if [ "$NPM_CHANNEL" = "latest" ]; then - git checkout -f -b "$BRANCH" - else - # Patch branch - NPM_VERSION=$(cat scripts/versions/tested_extension_stable) - echo "NPM_VERSION to base new branch on: $NPM_VERSION" - git checkout -f -b "$BRANCH" "$NPM_VERSION" - fi - - else - echo "Not setting up repo because ENVIRONMENT is not set" - fi - else - git checkout -f "$BRANCH" - echo "$BRANCH exists already." - echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" - fi -fi diff --git a/scripts/util.mjs b/scripts/util.mjs index 01fb01efb3..7f0677015d 100644 --- a/scripts/util.mjs +++ b/scripts/util.mjs @@ -5,10 +5,6 @@ import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) -export function writeToVersionFile({ fileName, content }) { - fs.writeFileSync(path.join(__dirname, 'versions', `./${fileName}`), content) -} - export function readVersionFile({ fileName = '' }) { return fs .readFileSync(path.join(__dirname, 'versions', `./${fileName}`), { @@ -25,4 +21,3 @@ export function getPackageJsonContent({ path: filePath }) { export function writeJsonToPackageJson({ content, path: filePath }) { fs.writeFileSync(filePath, JSON.stringify(content, undefined, 2)) } - diff --git a/scripts/versions/extension_latest b/scripts/versions/extension_latest deleted file mode 100644 index 77424f0941..0000000000 --- a/scripts/versions/extension_latest +++ /dev/null @@ -1 +0,0 @@ -31.12.2 \ No newline at end of file