From 596faec942d87e0707d7025fac89232d5f8229d2 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 12:44:01 -0400 Subject: [PATCH 1/6] github: support github annotations https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message rel: https://github.com/sbdchd/squawk/issues/537 --- .github/workflows/js.yml | 13 +- .github/workflows/python.yml | 12 +- .github/workflows/rust.yml | 353 +--------------------------------- .github/workflows/vscode.yml | 13 +- crates/squawk/src/github.rs | 7 +- crates/squawk/src/reporter.rs | 37 ++++ 6 files changed, 70 insertions(+), 365 deletions(-) diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index 61bc6f6d..946abd6a 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -1,12 +1,13 @@ name: Javascript on: - push: - branches: - - master - tags: - - "**" - pull_request: + workflow_dispatch: + # Disabled - push: + # branches: + # - master + # tags: + # - "**" + # Disabled - pull_request: jobs: pre_job: diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 9fa57eed..a73de947 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,13 +1,13 @@ name: python on: - push: - branches: - - master - tags: - - "**" - pull_request: workflow_dispatch: + # Disabled - push: + # branches: + # - master + # tags: + # - "**" + # Disabled - pull_request: permissions: contents: read diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ba5e8482..862d808f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,283 +1,15 @@ -name: Rust +name: Test Squawk GitHub Annotations on: push: branches: - master - tags: - - "**" pull_request: jobs: - pre_job: - runs-on: ubuntu-22.04 - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - paths_result: ${{ steps.skip_check.outputs.paths_result }} - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@c449d86cf33a2a6c7a4193264cc2578e2c3266d4 # pin@v4 - with: - paths_ignore: '["docs/**", "*.md"]' - - build: - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/') - - strategy: - fail-fast: false - matrix: - include: - - name: Linux x86_64 - os: ubuntu-22.04 - target: x86_64-unknown-linux-gnu - artifact_name: squawk-linux-x64 - vscode_artifact_name: linux-x64 - - - name: Linux arm64 - os: ubuntu-22.04 - target: aarch64-unknown-linux-gnu - artifact_name: squawk-linux-arm64 - vscode_artifact_name: linux-arm64 - rustflags: "-C linker=aarch64-linux-gnu-gcc" - - - name: Linux Alpine x86_64 - os: ubuntu-22.04 - target: x86_64-unknown-linux-musl - artifact_name: squawk-linux-musl-x64 - vscode_artifact_name: alpine-x64 - rustflags: "-C linker=rust-lld" - - - name: Windows x86_64 - os: windows-latest - target: x86_64-pc-windows-msvc - artifact_name: squawk-windows-x64.exe - vscode_artifact_name: win32-x64 - - - name: macOS x86_64 - os: macos-latest - target: x86_64-apple-darwin - artifact_name: squawk-darwin-x64 - vscode_artifact_name: darwin-x64 - - - name: macOS arm64 - os: macos-latest - target: aarch64-apple-darwin - artifact_name: squawk-darwin-arm64 - vscode_artifact_name: darwin-arm64 - - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Update apt repositories - if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'aarch64-unknown-linux-gnu' - run: sudo apt-get update - - - name: Install AArch64 target toolchain - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: sudo apt-get install gcc-aarch64-linux-gnu - - - name: Install x86_64-musl target toolchain - if: matrix.target == 'x86_64-unknown-linux-musl' - run: sudo apt-get install musl-tools - - - name: Install Toolchain - uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable - with: - toolchain: 1.88.0 - targets: ${{ matrix.target }} - - - name: Cache - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 - - - name: Build - run: RUSTFLAGS="${{ matrix.rustflags }}" cargo build --target ${{ matrix.target }} --release - shell: bash - - - name: Rename artifact (windows) - if: matrix.target == 'x86_64-pc-windows-msvc' - run: mv target/${{ matrix.target }}/release/squawk.exe target/release/${{ matrix.artifact_name }} - - - name: Rename artifact (linux, mac) - if: matrix.target != 'x86_64-pc-windows-msvc' - run: mv target/${{ matrix.target }}/release/squawk target/release/${{ matrix.artifact_name }} - - - name: Artifact - uses: actions/upload-artifact@v4 - with: - name: release-${{ matrix.artifact_name }} - path: target/release/${{ matrix.artifact_name }} - - - name: VSCode - Make server dir - shell: bash - run: mkdir squawk-vscode/server - - - name: VSCode - Copy binary into extension (windows) - if: matrix.target == 'x86_64-pc-windows-msvc' - shell: bash - run: cp target/release/${{ matrix.artifact_name }} squawk-vscode/server/squawk.exe - - - name: VSCode - Copy binary into extension (linux, mac) - if: matrix.target != 'x86_64-pc-windows-msvc' - shell: bash - run: cp target/release/${{ matrix.artifact_name }} squawk-vscode/server/squawk - - - name: VSCode - Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - - - name: VSCode - Setup node - uses: actions/setup-node@v3 - with: - node-version-file: "squawk-vscode/package.json" - cache-dependency-path: "squawk-vscode/pnpm-lock.yaml" - cache: "pnpm" - - - name: VSCode - Install JS dependencies - working-directory: "squawk-vscode" - run: pnpm install - - - name: VSCode - Build - working-directory: "squawk-vscode" - run: pnpm exec vsce pack --no-dependencies --target ${{ matrix.vscode_artifact_name }} - - - name: VSCode - Artifact - uses: actions/upload-artifact@v4 - with: - name: squawk-vscode-${{ matrix.vscode_artifact_name }} - path: squawk-vscode/*.vsix - - - name: Release - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # pin@v1 - if: startsWith(github.ref, 'refs/tags/') - with: - files: | - target/release/${{ matrix.artifact_name }} - squawk-vscode/*.vsix - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - publish-npm: - if: startsWith(github.ref, 'refs/tags/') - needs: [build] - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 - with: - node-version: 16 - registry-url: https://registry.npmjs.org/ - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} - - publish-docker: - if: startsWith(github.ref, 'refs/tags/') - needs: [build] - runs-on: ubuntu-22.04 - permissions: - contents: read - packages: write - attestations: write - id-token: write - env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest - type=ref,event=branch - type=sha - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push Docker image - uses: docker/build-push-action@v5 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - - deploy-playground: - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/') + test-annotations: runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Cache - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 - - - name: Install wasm-pack - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - - uses: pnpm/action-setup@v2 - with: - version: 8 - - uses: actions/setup-node@v3 - with: - node-version-file: "playground/package.json" - cache-dependency-path: "playground/pnpm-lock.yaml" - cache: "pnpm" - - - name: Install JS dependencies - working-directory: "playground" - run: pnpm install - - - name: Build - working-directory: "playground" - run: pnpm build - - - name: Deploy to Netlify - if: startsWith(github.ref, 'refs/tags/') - uses: nwtgck/actions-netlify@v2 - with: - publish-dir: "playground/dist" - production-branch: main - production-deploy: true - github-token: ${{ secrets.GITHUB_TOKEN }} - deploy-message: "Deploy from GitHub Actions" - fails-without-credentials: true - enable-pull-request-comment: false - enable-commit-comment: false - env: - NETLIFY_AUTH_TOKEN: ${{ secrets.PLAYGROUND_NETLIFY_AUTH_TOKEN }} - NETLIFY_SITE_ID: ${{ secrets.PLAYGROUND_NETLIFY_SITE_ID }} - - lint: - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' - - runs-on: ubuntu-22.04 - + steps: - name: Checkout uses: actions/checkout@v4 @@ -286,83 +18,12 @@ jobs: uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable with: toolchain: 1.88.0 - components: clippy, rustfmt - name: Cache uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 - - name: Get Clippy Version - run: cargo clippy --version - - - name: Lint - run: ./s/lint - - test: - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' - - runs-on: ubuntu-22.04 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Toolchain - uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable - with: - toolchain: 1.88.0 - - - name: Cache - uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 - - - name: Test - run: ./s/test - - check_version: - runs-on: ubuntu-22.04 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - with: - python-version-file: ".python-version" - - - name: Check versions are consistent - run: ./s/check-version - - publish-vscode: - if: startsWith(github.ref, 'refs/tags/') - needs: [build] - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version-file: "squawk-vscode/package.json" - cache-dependency-path: "squawk-vscode/pnpm-lock.yaml" - cache: "pnpm" - - name: Install JS dependencies - working-directory: "squawk-vscode" - run: pnpm install - - - name: Download all VS Code artifacts - uses: actions/download-artifact@v4 - with: - pattern: squawk-vscode-* - path: ./dist - - - name: Publish Extension (VS Code Marketplace) - working-directory: ./squawk-vscode - run: pnpm exec vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../dist/squawk-vscode-*/*.vsix + - name: Build Squawk + run: cargo build --release - - name: Publish Extension (Open VSX) - working-directory: ./squawk-vscode - run: pnpm exec ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../dist/squawk-vscode-*/*.vsix - timeout-minutes: 2 + - name: Run Squawk on example.sql + run: ./target/release/squawk example.sql \ No newline at end of file diff --git a/.github/workflows/vscode.yml b/.github/workflows/vscode.yml index 231cdad1..f31008c7 100644 --- a/.github/workflows/vscode.yml +++ b/.github/workflows/vscode.yml @@ -1,12 +1,13 @@ name: VSCode on: - push: - branches: - - master - tags: - - "**" - pull_request: + workflow_dispatch: + # Disabled - push: + # branches: + # - master + # tags: + # - "**" + # Disabled - pull_request: jobs: pre_job: diff --git a/crates/squawk/src/github.rs b/crates/squawk/src/github.rs index 30c9e1c7..6ea779e3 100644 --- a/crates/squawk/src/github.rs +++ b/crates/squawk/src/github.rs @@ -1,12 +1,13 @@ use crate::UploadToGithubArgs; use crate::config::Config; -use crate::reporter::{CheckReport, fmt_tty_violation}; +use crate::reporter::{CheckReport, fmt_github_annotations, fmt_tty_violation}; use crate::{file_finding::find_paths, reporter::check_files}; use anyhow::{Result, anyhow, bail}; use console::strip_ansi_codes; use log::info; use squawk_github::{GitHubApi, actions, app, comment_on_pr}; use squawk_linter::{Rule, Version}; +use std::io; const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -135,6 +136,10 @@ pub fn check_and_comment_on_pr( COMMENT_HEADER, )?; + let stdout = io::stdout(); + let mut handle = stdout.lock(); + fmt_github_annotations(&mut handle, &file_results)?; + let violations: usize = file_results.iter().map(|f| f.violations.len()).sum(); if fail_on_violations && violations > 0 { diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index a83cb089..663af896 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -42,10 +42,14 @@ fn check_sql( for e in parse_errors { let range_start = e.range().start(); let line_col = line_index.line_col(range_start); + let range_end = e.range().end(); + let line_end = line_index.line_col(range_end); violations.push(ReportViolation { file: path.to_string(), line: line_col.line as usize, + line_end: line_end.line as usize, column: line_col.col as usize, + column_end: line_end.col as usize, level: ViolationLevel::Error, help: None, range: e.range(), @@ -56,10 +60,14 @@ fn check_sql( for e in errors { let range_start = e.text_range.start(); let line_col = line_index.line_col(range_start); + let range_end = e.text_range.end(); + let line_end = line_index.line_col(range_end); violations.push(ReportViolation { file: path.to_string(), line: line_col.line as usize, + line_end: line_end.line as usize, column: line_col.col as usize, + column_end: line_end.col as usize, range: e.text_range, help: e.help, level: ViolationLevel::Warning, @@ -273,6 +281,8 @@ pub struct ReportViolation { pub message: String, pub help: Option, pub rule_name: String, + column_end: usize, + line_end: usize, } fn fmt_gcc(f: &mut W, reports: &[CheckReport]) -> Result<()> { @@ -324,6 +334,30 @@ fn fmt_json(f: &mut W, reports: Vec) -> Result<()> { Ok(()) } +pub fn fmt_github_annotations(f: &mut W, reports: &[CheckReport]) -> Result<()> { + for report in reports { + for violation in &report.violations { + let level = match violation.level { + ViolationLevel::Warning => "warning", + ViolationLevel::Error => "error", + }; + + writeln!( + f, + "::{level} file={file},line={line},col={col},endLine={line_end},endColumn={col_end},title={title}::{message}", + file = violation.file, + line = violation.line, + line_end = violation.line_end, + col = violation.column, + col_end = violation.column_end, + title = violation.rule_name, + message = violation.message, + )?; + } + } + Ok(()) +} + #[derive(Debug)] pub struct CheckReport { pub filename: String, @@ -336,6 +370,9 @@ pub fn print_violations( reports: Vec, reporter: &Reporter, ) -> Result<()> { + if std::env::var("GITHUB_ACTIONS").is_ok() { + fmt_github_annotations(writer, &reports)?; + } match reporter { Reporter::Gcc => fmt_gcc(writer, &reports), Reporter::Json => fmt_json(writer, reports), From d118c75e5a7f0409bf38ff9555491adbafac6809 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 12:50:58 -0400 Subject: [PATCH 2/6] fix annotation --- crates/squawk/src/reporter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index 663af896..8c22e62f 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -346,8 +346,8 @@ pub fn fmt_github_annotations(f: &mut W, reports: &[CheckReport]) f, "::{level} file={file},line={line},col={col},endLine={line_end},endColumn={col_end},title={title}::{message}", file = violation.file, - line = violation.line, - line_end = violation.line_end, + line = violation.line + 1, + line_end = violation.line_end + 1, col = violation.column, col_end = violation.column_end, title = violation.rule_name, From 53640d0a1d6dea3dd7cbfb43594aa82622f32faf Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 13:07:11 -0400 Subject: [PATCH 3/6] fix --- crates/squawk/src/github.rs | 2 + crates/squawk/src/main.rs | 3 ++ crates/squawk/src/reporter.rs | 38 +++++++++++-- ...violations_tty_and_github_annotations.snap | 53 +++++++++++++++++++ ...reporter__test_reporter__span_offsets.snap | 14 ++++- example.sql | 5 +- 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap diff --git a/crates/squawk/src/github.rs b/crates/squawk/src/github.rs index 6ea779e3..6bf9fa14 100644 --- a/crates/squawk/src/github.rs +++ b/crates/squawk/src/github.rs @@ -262,6 +262,8 @@ SELECT 1; message: "Adding a NOT NULL field requires exclusive locks and table rewrites." .to_string(), help: Some("Make the field nullable.".to_string()), + column_end: 0, + line_end: 1, }], }]; diff --git a/crates/squawk/src/main.rs b/crates/squawk/src/main.rs index 37b27e61..9eb0d602 100644 --- a/crates/squawk/src/main.rs +++ b/crates/squawk/src/main.rs @@ -255,6 +255,8 @@ Please open an issue at https://github.com/sbdchd/squawk/issues/new with the log debug(&mut handle, &found_paths, read_stdin, &kind, opts.verbose)?; } else { let reporter = opts.reporter.unwrap_or(Reporter::Tty); + let github_annotations = std::env::var("GITHUB_ACTIONS").is_ok() + && !std::env::var("SQUAWK_DISABLE_GITHUB_ANNOTATIONS").is_ok(); let exit_code = check_and_dump_files( &mut handle, &found_paths, @@ -264,6 +266,7 @@ Please open an issue at https://github.com/sbdchd/squawk/issues/new with the log pg_version, assume_in_transaction, &reporter, + github_annotations, )?; return Ok(exit_code); } diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index 8c22e62f..e83fdb06 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -166,6 +166,7 @@ pub fn check_and_dump_files( pg_version: Option, assume_in_transaction: bool, reporter: &Reporter, + github_annotations: bool, ) -> Result { let violations = check_files( path_patterns, @@ -178,7 +179,7 @@ pub fn check_and_dump_files( let ok = violations.iter().map(|x| x.violations.len()).sum::() == 0; - print_violations(f, violations, reporter)?; + print_violations(f, violations, reporter, github_annotations)?; Ok(if ok { ExitCode::SUCCESS @@ -281,8 +282,8 @@ pub struct ReportViolation { pub message: String, pub help: Option, pub rule_name: String, - column_end: usize, - line_end: usize, + pub column_end: usize, + pub line_end: usize, } fn fmt_gcc(f: &mut W, reports: &[CheckReport]) -> Result<()> { @@ -369,8 +370,9 @@ pub fn print_violations( writer: &mut W, reports: Vec, reporter: &Reporter, + github_annotations: bool, ) -> Result<()> { - if std::env::var("GITHUB_ACTIONS").is_ok() { + if github_annotations { fmt_github_annotations(writer, &reports)?; } match reporter { @@ -424,6 +426,7 @@ SELECT 1; &mut buff, vec![check_sql(sql, filename, &[], None, false)], &Reporter::Gcc, + false, ); assert!(res.is_ok()); @@ -437,6 +440,28 @@ SELECT 1; "###); } + #[test] + fn display_violations_tty_and_github_annotations() { + let sql = r#" + ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; +ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; +SELECT 1; +"#; + let filename = "main.sql"; + let mut buff = Vec::new(); + + let res = print_violations( + &mut buff, + vec![check_sql(sql, filename, &[], None, false)], + &Reporter::Tty, + true, + ); + + assert!(res.is_ok()); + // remove the color codes so tests behave in CI as they do locally + assert_snapshot!(strip_ansi_codes(&String::from_utf8_lossy(&buff))); + } + #[test] fn display_violations_tty() { let sql = r#" @@ -451,6 +476,7 @@ SELECT 1; &mut buff, vec![check_sql(sql, filename, &[], None, false)], &Reporter::Tty, + false, ); assert!(res.is_ok()); @@ -466,6 +492,7 @@ SELECT 1; &mut buff, vec![check_sql(sql, "main.sql", &[], None, false)], &Reporter::Tty, + false, ); assert!(res.is_ok()); @@ -487,10 +514,11 @@ SELECT 1; &mut buff, vec![check_sql(sql, filename, &[], None, false)], &Reporter::Json, + false, ); assert!(res.is_ok()); - assert_snapshot!(String::from_utf8_lossy(&buff), @r###"[{"file":"main.sql","line":1,"column":29,"level":"Warning","message":"Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required.","help":"Make the field nullable or add a non-VOLATILE DEFAULT","rule_name":"adding-required-field"},{"file":"main.sql","line":1,"column":29,"level":"Warning","message":"Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.","help":null,"rule_name":"prefer-robust-stmts"},{"file":"main.sql","line":1,"column":46,"level":"Warning","message":"Using 32-bit integer fields can result in hitting the max `int` limit.","help":"Use 64-bit integer values instead to prevent hitting this limit.","rule_name":"prefer-bigint-over-int"},{"file":"main.sql","line":2,"column":23,"level":"Warning","message":"Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required.","help":"Make the field nullable or add a non-VOLATILE DEFAULT","rule_name":"adding-required-field"},{"file":"main.sql","line":2,"column":23,"level":"Warning","message":"Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.","help":null,"rule_name":"prefer-robust-stmts"},{"file":"main.sql","line":2,"column":40,"level":"Warning","message":"Using 32-bit integer fields can result in hitting the max `int` limit.","help":"Use 64-bit integer values instead to prevent hitting this limit.","rule_name":"prefer-bigint-over-int"}]"###); + assert_snapshot!(String::from_utf8_lossy(&buff), @r#"[{"file":"main.sql","line":1,"column":29,"level":"Warning","message":"Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required.","help":"Make the field nullable or add a non-VOLATILE DEFAULT","rule_name":"adding-required-field","column_end":62,"line_end":1},{"file":"main.sql","line":1,"column":29,"level":"Warning","message":"Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.","help":null,"rule_name":"prefer-robust-stmts","column_end":62,"line_end":1},{"file":"main.sql","line":1,"column":46,"level":"Warning","message":"Using 32-bit integer fields can result in hitting the max `int` limit.","help":"Use 64-bit integer values instead to prevent hitting this limit.","rule_name":"prefer-bigint-over-int","column_end":53,"line_end":1},{"file":"main.sql","line":2,"column":23,"level":"Warning","message":"Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required.","help":"Make the field nullable or add a non-VOLATILE DEFAULT","rule_name":"adding-required-field","column_end":56,"line_end":2},{"file":"main.sql","line":2,"column":23,"level":"Warning","message":"Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.","help":null,"rule_name":"prefer-robust-stmts","column_end":56,"line_end":2},{"file":"main.sql","line":2,"column":40,"level":"Warning","message":"Using 32-bit integer fields can result in hitting the max `int` limit.","help":"Use 64-bit integer values instead to prevent hitting this limit.","rule_name":"prefer-bigint-over-int","column_end":47,"line_end":2}]"#); } #[test] diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap new file mode 100644 index 00000000..5d5590fa --- /dev/null +++ b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap @@ -0,0 +1,53 @@ +--- +source: crates/squawk/src/reporter.rs +expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" +--- +::warning file=main.sql,line=2,col=29,endLine=2,endColumn=62,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. +::warning file=main.sql,line=2,col=29,endLine=2,endColumn=62,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +::warning file=main.sql,line=2,col=46,endLine=2,endColumn=53,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. +::warning file=main.sql,line=3,col=23,endLine=3,endColumn=56,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. +::warning file=main.sql,line=3,col=23,endLine=3,endColumn=56,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +::warning file=main.sql,line=3,col=40,endLine=3,endColumn=47,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. +warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. + --> main.sql:2:30 + | +2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + | --------------------------------- + | + = help: Make the field nullable or add a non-VOLATILE DEFAULT +warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. + --> main.sql:2:30 + | +2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + | --------------------------------- + | +warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. + --> main.sql:2:47 + | +2 | ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; + | ------- + | + = help: Use 64-bit integer values instead to prevent hitting this limit. +warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. + --> main.sql:3:24 + | +3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + | --------------------------------- + | + = help: Make the field nullable or add a non-VOLATILE DEFAULT +warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. + --> main.sql:3:24 + | +3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + | --------------------------------- + | +warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. + --> main.sql:3:41 + | +3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; + | ------- + | + = help: Use 64-bit integer values instead to prevent hitting this limit. + +Find detailed examples and solutions for each rule at https://squawkhq.com/docs/rules +Found 6 issues in 1 file (checked 1 source file) diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap index e206e57d..6dcd212a 100644 --- a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap +++ b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__span_offsets.snap @@ -1,5 +1,5 @@ --- -source: crates/cli/src/reporter.rs +source: crates/squawk/src/reporter.rs expression: "check_sql(sql, filename, &[], None, false)" --- CheckReport { @@ -17,6 +17,8 @@ CheckReport { "Make the field nullable or add a non-VOLATILE DEFAULT", ), rule_name: "adding-required-field", + column_end: 62, + line_end: 2, }, ReportViolation { file: "main.sql", @@ -27,6 +29,8 @@ CheckReport { message: "Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.", help: None, rule_name: "prefer-robust-stmts", + column_end: 62, + line_end: 2, }, ReportViolation { file: "main.sql", @@ -39,6 +43,8 @@ CheckReport { "Use 64-bit integer values instead to prevent hitting this limit.", ), rule_name: "prefer-bigint-over-int", + column_end: 53, + line_end: 2, }, ReportViolation { file: "main.sql", @@ -51,6 +57,8 @@ CheckReport { "Make the field nullable or add a non-VOLATILE DEFAULT", ), rule_name: "adding-required-field", + column_end: 56, + line_end: 3, }, ReportViolation { file: "main.sql", @@ -61,6 +69,8 @@ CheckReport { message: "Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through.", help: None, rule_name: "prefer-robust-stmts", + column_end: 56, + line_end: 3, }, ReportViolation { file: "main.sql", @@ -73,6 +83,8 @@ CheckReport { "Use 64-bit integer values instead to prevent hitting this limit.", ), rule_name: "prefer-bigint-over-int", + column_end: 47, + line_end: 3, }, ], } diff --git a/example.sql b/example.sql index 32f816f5..baef0893 100644 --- a/example.sql +++ b/example.sql @@ -9,6 +9,9 @@ CREATE TABLE "core_bar" ( CREATE INDEX "field_name_idx" ON "table_name" ("field_name"); -ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name); +ALTER TABLE table_name + ADD CONSTRAINT + field_name_constraint + UNIQUE (field_name); COMMIT; From d2bd4c832ffa0528c42bfcc445f9a81a93af8654 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 13:13:42 -0400 Subject: [PATCH 4/6] fix --- crates/squawk/src/reporter.rs | 5 +++- ...violations_tty_and_github_annotations.snap | 26 ++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/crates/squawk/src/reporter.rs b/crates/squawk/src/reporter.rs index e83fdb06..4359894c 100644 --- a/crates/squawk/src/reporter.rs +++ b/crates/squawk/src/reporter.rs @@ -444,7 +444,10 @@ SELECT 1; fn display_violations_tty_and_github_annotations() { let sql = r#" ALTER TABLE "core_recipe" ADD COLUMN "foo" integer NOT NULL; -ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; +-- multi line example +ALTER TABLE "core_foo" + ADD COLUMN "bar" + integer NOT NULL; SELECT 1; "#; let filename = "main.sql"; diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap index 5d5590fa..43026010 100644 --- a/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap +++ b/crates/squawk/src/snapshots/squawk__reporter__test_reporter__display_violations_tty_and_github_annotations.snap @@ -5,9 +5,9 @@ expression: "strip_ansi_codes(&String::from_utf8_lossy(&buff))" ::warning file=main.sql,line=2,col=29,endLine=2,endColumn=62,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. ::warning file=main.sql,line=2,col=29,endLine=2,endColumn=62,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. ::warning file=main.sql,line=2,col=46,endLine=2,endColumn=53,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. -::warning file=main.sql,line=3,col=23,endLine=3,endColumn=56,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. -::warning file=main.sql,line=3,col=23,endLine=3,endColumn=56,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. -::warning file=main.sql,line=3,col=40,endLine=3,endColumn=47,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. +::warning file=main.sql,line=5,col=2,endLine=6,endColumn=20,title=adding-required-field::Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. +::warning file=main.sql,line=5,col=2,endLine=6,endColumn=20,title=prefer-robust-stmts::Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. +::warning file=main.sql,line=6,col=4,endLine=6,endColumn=11,title=prefer-bigint-over-int::Using 32-bit integer fields can result in hitting the max `int` limit. warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. --> main.sql:2:30 | @@ -29,23 +29,25 @@ warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitti | = help: Use 64-bit integer values instead to prevent hitting this limit. warning[adding-required-field]: Adding a new column that is `NOT NULL` and has no default value to an existing table effectively makes it required. - --> main.sql:3:24 + --> main.sql:5:3 | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | --------------------------------- +5 | / ADD COLUMN "bar" +6 | | integer NOT NULL; + | |____________________- | = help: Make the field nullable or add a non-VOLATILE DEFAULT warning[prefer-robust-stmts]: Missing `IF NOT EXISTS`, the migration can't be rerun if it fails part way through. - --> main.sql:3:24 + --> main.sql:5:3 | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | --------------------------------- +5 | / ADD COLUMN "bar" +6 | | integer NOT NULL; + | |____________________- | warning[prefer-bigint-over-int]: Using 32-bit integer fields can result in hitting the max `int` limit. - --> main.sql:3:41 + --> main.sql:6:5 | -3 | ALTER TABLE "core_foo" ADD COLUMN "bar" integer NOT NULL; - | ------- +6 | integer NOT NULL; + | ------- | = help: Use 64-bit integer values instead to prevent hitting this limit. From c656b95a2381d64d0f6e6208003ca572db36c245 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 13:14:47 -0400 Subject: [PATCH 5/6] fix --- .github/workflows/js.yml | 13 +- .github/workflows/python.yml | 12 +- .github/workflows/rust.yml | 353 ++++++++++++++++++++++++++++++++++- .github/workflows/vscode.yml | 13 +- example.sql | 5 +- 5 files changed, 365 insertions(+), 31 deletions(-) diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index 946abd6a..61bc6f6d 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -1,13 +1,12 @@ name: Javascript on: - workflow_dispatch: - # Disabled - push: - # branches: - # - master - # tags: - # - "**" - # Disabled - pull_request: + push: + branches: + - master + tags: + - "**" + pull_request: jobs: pre_job: diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a73de947..9fa57eed 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,13 +1,13 @@ name: python on: + push: + branches: + - master + tags: + - "**" + pull_request: workflow_dispatch: - # Disabled - push: - # branches: - # - master - # tags: - # - "**" - # Disabled - pull_request: permissions: contents: read diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 862d808f..ba5e8482 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,15 +1,283 @@ -name: Test Squawk GitHub Annotations +name: Rust on: push: branches: - master + tags: + - "**" pull_request: jobs: - test-annotations: + pre_job: + runs-on: ubuntu-22.04 + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + paths_result: ${{ steps.skip_check.outputs.paths_result }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@c449d86cf33a2a6c7a4193264cc2578e2c3266d4 # pin@v4 + with: + paths_ignore: '["docs/**", "*.md"]' + + build: + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/') + + strategy: + fail-fast: false + matrix: + include: + - name: Linux x86_64 + os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + artifact_name: squawk-linux-x64 + vscode_artifact_name: linux-x64 + + - name: Linux arm64 + os: ubuntu-22.04 + target: aarch64-unknown-linux-gnu + artifact_name: squawk-linux-arm64 + vscode_artifact_name: linux-arm64 + rustflags: "-C linker=aarch64-linux-gnu-gcc" + + - name: Linux Alpine x86_64 + os: ubuntu-22.04 + target: x86_64-unknown-linux-musl + artifact_name: squawk-linux-musl-x64 + vscode_artifact_name: alpine-x64 + rustflags: "-C linker=rust-lld" + + - name: Windows x86_64 + os: windows-latest + target: x86_64-pc-windows-msvc + artifact_name: squawk-windows-x64.exe + vscode_artifact_name: win32-x64 + + - name: macOS x86_64 + os: macos-latest + target: x86_64-apple-darwin + artifact_name: squawk-darwin-x64 + vscode_artifact_name: darwin-x64 + + - name: macOS arm64 + os: macos-latest + target: aarch64-apple-darwin + artifact_name: squawk-darwin-arm64 + vscode_artifact_name: darwin-arm64 + + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Update apt repositories + if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'aarch64-unknown-linux-gnu' + run: sudo apt-get update + + - name: Install AArch64 target toolchain + if: matrix.target == 'aarch64-unknown-linux-gnu' + run: sudo apt-get install gcc-aarch64-linux-gnu + + - name: Install x86_64-musl target toolchain + if: matrix.target == 'x86_64-unknown-linux-musl' + run: sudo apt-get install musl-tools + + - name: Install Toolchain + uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable + with: + toolchain: 1.88.0 + targets: ${{ matrix.target }} + + - name: Cache + uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 + + - name: Build + run: RUSTFLAGS="${{ matrix.rustflags }}" cargo build --target ${{ matrix.target }} --release + shell: bash + + - name: Rename artifact (windows) + if: matrix.target == 'x86_64-pc-windows-msvc' + run: mv target/${{ matrix.target }}/release/squawk.exe target/release/${{ matrix.artifact_name }} + + - name: Rename artifact (linux, mac) + if: matrix.target != 'x86_64-pc-windows-msvc' + run: mv target/${{ matrix.target }}/release/squawk target/release/${{ matrix.artifact_name }} + + - name: Artifact + uses: actions/upload-artifact@v4 + with: + name: release-${{ matrix.artifact_name }} + path: target/release/${{ matrix.artifact_name }} + + - name: VSCode - Make server dir + shell: bash + run: mkdir squawk-vscode/server + + - name: VSCode - Copy binary into extension (windows) + if: matrix.target == 'x86_64-pc-windows-msvc' + shell: bash + run: cp target/release/${{ matrix.artifact_name }} squawk-vscode/server/squawk.exe + + - name: VSCode - Copy binary into extension (linux, mac) + if: matrix.target != 'x86_64-pc-windows-msvc' + shell: bash + run: cp target/release/${{ matrix.artifact_name }} squawk-vscode/server/squawk + + - name: VSCode - Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: VSCode - Setup node + uses: actions/setup-node@v3 + with: + node-version-file: "squawk-vscode/package.json" + cache-dependency-path: "squawk-vscode/pnpm-lock.yaml" + cache: "pnpm" + + - name: VSCode - Install JS dependencies + working-directory: "squawk-vscode" + run: pnpm install + + - name: VSCode - Build + working-directory: "squawk-vscode" + run: pnpm exec vsce pack --no-dependencies --target ${{ matrix.vscode_artifact_name }} + + - name: VSCode - Artifact + uses: actions/upload-artifact@v4 + with: + name: squawk-vscode-${{ matrix.vscode_artifact_name }} + path: squawk-vscode/*.vsix + + - name: Release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # pin@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + target/release/${{ matrix.artifact_name }} + squawk-vscode/*.vsix + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-npm: + if: startsWith(github.ref, 'refs/tags/') + needs: [build] + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{secrets.npm_token}} + + publish-docker: + if: startsWith(github.ref, 'refs/tags/') + needs: [build] + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=raw,value=latest + type=ref,event=branch + type=sha + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + deploy-playground: + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-22.04 - + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache + uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 + + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + - uses: pnpm/action-setup@v2 + with: + version: 8 + - uses: actions/setup-node@v3 + with: + node-version-file: "playground/package.json" + cache-dependency-path: "playground/pnpm-lock.yaml" + cache: "pnpm" + + - name: Install JS dependencies + working-directory: "playground" + run: pnpm install + + - name: Build + working-directory: "playground" + run: pnpm build + + - name: Deploy to Netlify + if: startsWith(github.ref, 'refs/tags/') + uses: nwtgck/actions-netlify@v2 + with: + publish-dir: "playground/dist" + production-branch: main + production-deploy: true + github-token: ${{ secrets.GITHUB_TOKEN }} + deploy-message: "Deploy from GitHub Actions" + fails-without-credentials: true + enable-pull-request-comment: false + enable-commit-comment: false + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.PLAYGROUND_NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.PLAYGROUND_NETLIFY_SITE_ID }} + + lint: + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' + + runs-on: ubuntu-22.04 + steps: - name: Checkout uses: actions/checkout@v4 @@ -18,12 +286,83 @@ jobs: uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable with: toolchain: 1.88.0 + components: clippy, rustfmt - name: Cache uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 - - name: Build Squawk - run: cargo build --release + - name: Get Clippy Version + run: cargo clippy --version + + - name: Lint + run: ./s/lint + + test: + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' + + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Toolchain + uses: dtolnay/rust-toolchain@4305c38b25d97ef35a8ad1f985ccf2d2242004f2 # stable + with: + toolchain: 1.88.0 + + - name: Cache + uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # pin@v2 + + - name: Test + run: ./s/test + + check_version: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version-file: ".python-version" + + - name: Check versions are consistent + run: ./s/check-version + + publish-vscode: + if: startsWith(github.ref, 'refs/tags/') + needs: [build] + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version-file: "squawk-vscode/package.json" + cache-dependency-path: "squawk-vscode/pnpm-lock.yaml" + cache: "pnpm" + - name: Install JS dependencies + working-directory: "squawk-vscode" + run: pnpm install + + - name: Download all VS Code artifacts + uses: actions/download-artifact@v4 + with: + pattern: squawk-vscode-* + path: ./dist + + - name: Publish Extension (VS Code Marketplace) + working-directory: ./squawk-vscode + run: pnpm exec vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../dist/squawk-vscode-*/*.vsix - - name: Run Squawk on example.sql - run: ./target/release/squawk example.sql \ No newline at end of file + - name: Publish Extension (Open VSX) + working-directory: ./squawk-vscode + run: pnpm exec ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../dist/squawk-vscode-*/*.vsix + timeout-minutes: 2 diff --git a/.github/workflows/vscode.yml b/.github/workflows/vscode.yml index f31008c7..231cdad1 100644 --- a/.github/workflows/vscode.yml +++ b/.github/workflows/vscode.yml @@ -1,13 +1,12 @@ name: VSCode on: - workflow_dispatch: - # Disabled - push: - # branches: - # - master - # tags: - # - "**" - # Disabled - pull_request: + push: + branches: + - master + tags: + - "**" + pull_request: jobs: pre_job: diff --git a/example.sql b/example.sql index baef0893..32f816f5 100644 --- a/example.sql +++ b/example.sql @@ -9,9 +9,6 @@ CREATE TABLE "core_bar" ( CREATE INDEX "field_name_idx" ON "table_name" ("field_name"); -ALTER TABLE table_name - ADD CONSTRAINT - field_name_constraint - UNIQUE (field_name); +ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name); COMMIT; From f38b9026c234aec0b32d9aea11a4ebfe6b555ae5 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 12 Jul 2025 13:18:20 -0400 Subject: [PATCH 6/6] fix --- ...eporter__test_check_files__check_files_invalid_syntax.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/squawk/src/snapshots/squawk__reporter__test_check_files__check_files_invalid_syntax.snap b/crates/squawk/src/snapshots/squawk__reporter__test_check_files__check_files_invalid_syntax.snap index 3fd6484a..d9728fa9 100644 --- a/crates/squawk/src/snapshots/squawk__reporter__test_check_files__check_files_invalid_syntax.snap +++ b/crates/squawk/src/snapshots/squawk__reporter__test_check_files__check_files_invalid_syntax.snap @@ -1,5 +1,5 @@ --- -source: crates/cli/src/reporter.rs +source: crates/squawk/src/reporter.rs expression: val --- -[{"column":6,"file":"test.sql","help":null,"level":"Error","line":1,"message":"expected SEMICOLON","rule_name":"syntax-error"},{"column":7,"file":"test.sql","help":null,"level":"Error","line":1,"message":"expected command, found ERROR","rule_name":"syntax-error"}] +[{"column":6,"column_end":6,"file":"test.sql","help":null,"level":"Error","line":1,"line_end":1,"message":"expected SEMICOLON","rule_name":"syntax-error"},{"column":7,"column_end":7,"file":"test.sql","help":null,"level":"Error","line":1,"line_end":1,"message":"expected command, found ERROR","rule_name":"syntax-error"}]