diff --git a/.eslintrc.js b/.eslintrc.js index 9a84e742..46a2a2c6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,7 +23,7 @@ module.exports = { 'node/no-unsupported-features/es-syntax': 'off', 'node/no-extraneous-import': 'off', "node/no-missing-import": ["error", { - "allowModules": ["vscode"] + "allowModules": ["vscode", "@deepnote/sqlint", "@deepnote/sql-parser", "@deepnote/sql-language-server", "sql-language-server"] }], 'import/first': 0, 'import/named': 2, diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..ff15886f --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,109 @@ +name: CD + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + publish: + name: Publish to npm + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: release + # Only run if the release tag follows the package-scoped pattern: @deepnote/package-name@version + if: startsWith(github.event.release.tag_name, '@deepnote/') + + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Extract package info from tag + id: package_info + env: + TAG: ${{ github.event.release.tag_name }} + run: | + # Extract package name and version from tag (format: @deepnote/package-name@version) + if [[ ! "$TAG" =~ ^(@deepnote/[^@]+)@(.+)$ ]]; then + echo "Error: Tag must follow format @deepnote/package-name@version" + exit 1 + fi + + PACKAGE_NAME="${BASH_REMATCH[1]}" + TAG_VERSION="${BASH_REMATCH[2]}" + + echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT + echo "tag_version=$TAG_VERSION" >> $GITHUB_OUTPUT + + echo "Detected package: $PACKAGE_NAME" + echo "Detected version: $TAG_VERSION" + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '18' + cache: 'yarn' + registry-url: 'https://registry.npmjs.org/' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Validate package version + env: + PACKAGE_NAME: ${{ steps.package_info.outputs.package_name }} + TAG_VERSION: ${{ steps.package_info.outputs.tag_version }} + run: | + # Map package name to directory + case "$PACKAGE_NAME" in + "@deepnote/sql-parser") PACKAGE_PATH="packages/sql-parser" ;; + "@deepnote/sqlint") PACKAGE_PATH="packages/sqlint" ;; + "@deepnote/sql-language-server") PACKAGE_PATH="packages/server" ;; + *) echo "Error: Unknown package $PACKAGE_NAME"; exit 1 ;; + esac + + if [[ ! -f "$PACKAGE_PATH/package.json" ]]; then + echo "Error: Package not found at $PACKAGE_PATH" + exit 1 + fi + + PACKAGE_VERSION=$(node -p "require('./$PACKAGE_PATH/package.json').version") + + if [[ "$PACKAGE_VERSION" != "$TAG_VERSION" ]]; then + echo "Error: Version mismatch!" + echo " Tag version: $TAG_VERSION" + echo " Package version: $PACKAGE_VERSION" + exit 1 + fi + + echo "Version validation passed: $TAG_VERSION" + + - name: Build dependencies and package + env: + PACKAGE_NAME: ${{ steps.package_info.outputs.package_name }} + run: | + case "$PACKAGE_NAME" in + "@deepnote/sql-parser") + yarn workspace @deepnote/sql-parser build + ;; + "@deepnote/sqlint") + yarn workspace @deepnote/sql-parser build + yarn build:sqlint + ;; + "@deepnote/sql-language-server") + yarn npm:prepublish + ;; + esac + + - name: Publish to npm + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + PACKAGE_NAME: ${{ steps.package_info.outputs.package_name }} + run: | + case "$PACKAGE_NAME" in + "@deepnote/sql-parser") cd packages/sql-parser ;; + "@deepnote/sqlint") cd packages/sqlint ;; + "@deepnote/sql-language-server") cd packages/server ;; + esac + npm publish --access public diff --git a/packages/server/package.json b/packages/server/package.json index 6b49ace1..0ed60c0e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,5 +1,5 @@ { - "name": "sql-language-server", + "name": "@deepnote/sql-language-server", "version": "1.7.0", "main": "dist/src/index.js", "bin": { @@ -48,7 +48,7 @@ "mysql2": "^2.3.0", "node-ssh-forward": "^0.6.3", "pg": "^8.9.0", - "sqlint": "^1.7.0", + "@deepnote/sqlint": "^1.7.0", "sqlite3": "^5.0.3", "vscode-languageclient": "^6.1.3", "vscode-languageserver": "8.0.0-next.8", diff --git a/packages/server/src/cache.ts b/packages/server/src/cache.ts index 3f4ad2da..35e23bdf 100644 --- a/packages/server/src/cache.ts +++ b/packages/server/src/cache.ts @@ -1,4 +1,4 @@ -import { Diagnostic as SQLintDiagnostic } from 'sqlint' +import { Diagnostic as SQLintDiagnostic } from '@deepnote/sqlint' import { Diagnostic, Range } from 'vscode-languageserver' import { stubLogger } from './logger' diff --git a/packages/server/src/createDiagnostics.ts b/packages/server/src/createDiagnostics.ts index 77448faa..b0510995 100644 --- a/packages/server/src/createDiagnostics.ts +++ b/packages/server/src/createDiagnostics.ts @@ -1,7 +1,7 @@ import { parse, ParseError } from '@deepnote/sql-parser' import { PublishDiagnosticsParams, Diagnostic } from 'vscode-languageserver' import { DiagnosticSeverity } from 'vscode-languageserver-types' -import { lint, ErrorLevel, LintResult, RawConfig } from 'sqlint' +import { lint, ErrorLevel, LintResult, RawConfig } from '@deepnote/sqlint' import cache, { LintCache } from './cache' import { stubLogger } from './logger' diff --git a/packages/server/src/createServer.ts b/packages/server/src/createServer.ts index ec641a98..59e5f34d 100644 --- a/packages/server/src/createServer.ts +++ b/packages/server/src/createServer.ts @@ -17,8 +17,8 @@ import { Position, CodeActionKind, } from 'vscode-languageserver-types' -import { lint, LintResult } from 'sqlint' -import { RawConfig } from 'sqlint' +import { lint, LintResult, FixDescription } from '@deepnote/sqlint' +import { RawConfig } from '@deepnote/sqlint' import cache from './cache' import { complete } from './complete' import createDiagnostics from './createDiagnostics' @@ -291,7 +291,7 @@ export function createServerWithConnection(connection: Connection) { documentChanges: [ TextDocumentEdit.create( { uri: params.textDocument.uri, version: document.version }, - fixes.map((v) => { + fixes.map((v: FixDescription) => { const edit = v.range.startOffset === v.range.endOffset ? TextEdit.insert( diff --git a/packages/sqlint/package.json b/packages/sqlint/package.json index 86fe9966..51c313cc 100644 --- a/packages/sqlint/package.json +++ b/packages/sqlint/package.json @@ -1,5 +1,5 @@ { - "name": "sqlint", + "name": "@deepnote/sqlint", "version": "1.7.0", "main": "dist/src/index", "bin": "bin/cli.js", diff --git a/packages/sqlint/src/index.ts b/packages/sqlint/src/index.ts index d830e1a9..e343cfa4 100644 --- a/packages/sqlint/src/index.ts +++ b/packages/sqlint/src/index.ts @@ -1,7 +1,7 @@ import { lint, LintResult } from './cli/lint' import { RawConfig } from './cli/loadConfig' import { ErrorLevel, Diagnostic, Config } from './rules/index' -import { applyFixes } from './fixer' +import { applyFixes, FixDescription } from './fixer' export { lint, @@ -11,4 +11,5 @@ export { RawConfig, Config, applyFixes, + FixDescription, } diff --git a/packages/sqlint/tsconfig.json b/packages/sqlint/tsconfig.json index 8fa4a4d2..1a8fa786 100644 --- a/packages/sqlint/tsconfig.json +++ b/packages/sqlint/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "rootDir": ".", "outDir": "dist", - "declaration": true + "declaration": true, + "composite": true }, "exclude": [ "node_modules", diff --git a/tsconfig.json b/tsconfig.json index 3930485f..cb57b1e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,9 +13,9 @@ "baseUrl": ".", "composite": true, "paths": { - "sql-language-server": ["packages/server/*"], + "@deepnote/sql-language-server": ["packages/server/*"], "@deepnote/sql-parser": ["packages/sql-parser/*"], - "sqlint": ["packages/sqlint/*"] + "@deepnote/sqlint": ["packages/sqlint/*"] } }, }