diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f6e068..83ec495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.7 — 2026-09-22 + +### Fixed + +- **The GitHub Action could report green while doing nothing.** It installed the + package globally with `npm i -g github:…` and then called `sia`; on a runner that + install extracted nothing onto PATH, so the next step died with + `sia: command not found` (exit 127), and because that step carried + `continue-on-error: true` the check still passed. The Action now runs the bundle + it ships (`node "$GITHUB_ACTION_PATH/dist/cli.js"`), which removes the install, + the PATH dependency and the npm extraction failure in one move. + `continue-on-error` is gone: an exit above 1 fails the step loudly, while + findings at or above `--fail-on` remain the only thing that can redden a build. + It also exposes a `cli` output, so a later step in the caller's job reuses the + same binary instead of assuming a global `sia` exists. + +Caught by opening a real pull request against this repository, which is the only +way that class of bug shows up. + ## 0.1.6 — 2026-09-22 Six findings from two sources: running the tool over other people's projects diff --git a/README.md b/README.md index c7a399f..be32f83 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # sql-index-advisor -[![CI](https://img.shields.io/github/actions/workflow/status/JingYu-create520/sql-index-advisor/ci.yml?branch=main&label=CI)](https://github.com/JingYu-create520/sql-index-advisor/actions/workflows/ci.yml) [![release v0.1.6](https://img.shields.io/github/v/tag/JingYu-create520/sql-index-advisor?label=release)](https://github.com/JingYu-create520/sql-index-advisor/releases/tag/v0.1.6) [![license MIT](https://img.shields.io/github/license/JingYu-create520/sql-index-advisor)](LICENSE) +[![CI](https://img.shields.io/github/actions/workflow/status/JingYu-create520/sql-index-advisor/ci.yml?branch=main&label=CI)](https://github.com/JingYu-create520/sql-index-advisor/actions/workflows/ci.yml) [![release v0.1.7](https://img.shields.io/github/v/tag/JingYu-create520/sql-index-advisor?label=release)](https://github.com/JingYu-create520/sql-index-advisor/releases/tag/v0.1.7) [![license MIT](https://img.shields.io/github/license/JingYu-create520/sql-index-advisor)](LICENSE) **Offline index advisor for MySQL / MyBatis. Slow query log in, index recommendations and migration SQL out.** diff --git a/README.zh-CN.md b/README.zh-CN.md index 5b0ec7f..22fee94 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,6 +1,6 @@ # sql-index-advisor -[![CI](https://img.shields.io/github/actions/workflow/status/JingYu-create520/sql-index-advisor/ci.yml?branch=main&label=CI)](https://github.com/JingYu-create520/sql-index-advisor/actions/workflows/ci.yml) [![release v0.1.6](https://img.shields.io/github/v/tag/JingYu-create520/sql-index-advisor?label=release)](https://github.com/JingYu-create520/sql-index-advisor/releases/tag/v0.1.6) [![license MIT](https://img.shields.io/github/license/JingYu-create520/sql-index-advisor)](LICENSE) +[![CI](https://img.shields.io/github/actions/workflow/status/JingYu-create520/sql-index-advisor/ci.yml?branch=main&label=CI)](https://github.com/JingYu-create520/sql-index-advisor/actions/workflows/ci.yml) [![release v0.1.7](https://img.shields.io/github/v/tag/JingYu-create520/sql-index-advisor?label=release)](https://github.com/JingYu-create520/sql-index-advisor/releases/tag/v0.1.7) [![license MIT](https://img.shields.io/github/license/JingYu-create520/sql-index-advisor)](LICENSE) **面向 MySQL / MyBatis 的离线索引顾问。慢查询日志进,索引建议 + 迁移 SQL 出。** diff --git a/action.yml b/action.yml index c21c73d..feedc39 100644 --- a/action.yml +++ b/action.yml @@ -36,24 +36,46 @@ inputs: required: false default: "" cli: - description: "CLI command to run. Default installs `sia` from GitHub in this job." + description: "Command to run the CLI with. Empty uses the bundle shipped in this repository, so no install step is needed." required: false - default: "sia" + default: "" outputs: report-file: description: "Path to the JSON report artifact written into the workspace" value: ${{ steps.report.outputs.report-file }} + cli: + description: "The command that runs the CLI in this job, for a later step that wants a second look at the same input" + value: ${{ steps.cli.outputs.bin }} runs: using: "composite" steps: - - name: "Install sql-index-advisor" - # Skipped when the caller supplies its own `cli`, so a fork or a local - # build stays usable without going through npm. - if: ${{ inputs.cli == 'sia' }} + - name: "Resolve the CLI" + id: "cli" + # Running the committed dist/cli.js is the default on purpose. The earlier + # design installed the package globally with `npm i -g github:…` and then + # called `sia`; on a GitHub runner that install produced nothing on PATH + # ("sia: command not found", exit 127) while the step that consumed it kept + # `continue-on-error`, so the check still reported green. No install, no + # PATH, no npm tar-extraction surprises: the action ships its own bundle. shell: bash - run: npm i -g github:JingYu-create520/sql-index-advisor + env: + OVERRIDE: ${{ inputs.cli }} + run: | + set -euo pipefail + if [ -n "${OVERRIDE}" ]; then + echo "bin=${OVERRIDE}" >> "$GITHUB_OUTPUT" + echo "Using the CLI supplied by the caller." + else + entry="${GITHUB_ACTION_PATH}/dist/cli.js" + if [ ! -f "${entry}" ]; then + echo "::error::${entry} is missing. Pin a tag from 0.1.6 or later, or pass the cli input." + exit 1 + fi + echo "bin=node ${entry}" >> "$GITHUB_OUTPUT" + node "${entry}" --version + fi - name: "Collect input (guards against injecting user text into the shell)" id: "config" @@ -67,33 +89,39 @@ runs: - name: "Annotate findings" id: "report" - # The annotation step must never break a build on its own: adoption first. - continue-on-error: true + shell: bash env: + CLI: ${{ steps.cli.outputs.bin }} PATH_ARG: ${{ inputs.path }} SCHEMA_FLAG: ${{ steps.config.outputs.schema-flag }} MIN_SEVERITY: ${{ inputs.min-severity }} MYSQL_VERSION: ${{ inputs.mysql-version }} TOP: ${{ inputs.top }} EXTRA_ARGS: ${{ inputs.args }} - CLI: ${{ inputs.cli }} - shell: bash run: | - set -o pipefail + set +e + # Findings must not break a build here: the job below decides that. A + # non-zero exit larger than 1 means the tool itself never ran, and that is + # a broken review, not a clean bill of health, so it has to be loud. ${CLI} "${PATH_ARG}" ${SCHEMA_FLAG} \ --format github \ --min-severity "${MIN_SEVERITY}" \ --mysql-version "${MYSQL_VERSION}" \ --top "${TOP}" \ ${EXTRA_ARGS} | tee sia-annotations.txt + code=${PIPESTATUS[0]} + if [ "${code}" -gt 1 ]; then + echo "::error::sql-index-advisor failed to run (exit ${code}). Check the path and schema inputs; the annotations below, if any, are incomplete." + exit 1 + fi + set -e ${CLI} "${PATH_ARG}" ${SCHEMA_FLAG} \ --format json \ --min-severity "${MIN_SEVERITY}" \ --mysql-version "${MYSQL_VERSION}" \ --top "${TOP}" \ - ${EXTRA_ARGS} > sia-report.json || true - + ${EXTRA_ARGS} > sia-report.json echo "report-file=sia-report.json" >> "$GITHUB_OUTPUT" { @@ -109,12 +137,12 @@ runs: - name: "Fail the job (only when fail-on is set)" if: ${{ inputs.fail-on != 'off' }} env: + CLI: ${{ steps.cli.outputs.bin }} PATH_ARG: ${{ inputs.path }} SCHEMA_FLAG: ${{ steps.config.outputs.schema-flag }} FAIL_ON: ${{ inputs.fail-on }} MYSQL_VERSION: ${{ inputs.mysql-version }} EXTRA_ARGS: ${{ inputs.args }} - CLI: ${{ inputs.cli }} shell: bash run: | # Actions runs `run:` blocks under `bash -e`, so a non-zero exit would diff --git a/examples/github-action/pr-review.yml b/examples/github-action/pr-review.yml index e1e8a29..fb0b56a 100644 --- a/examples/github-action/pr-review.yml +++ b/examples/github-action/pr-review.yml @@ -24,7 +24,9 @@ jobs: # Line-level comments: scan the mapper directory and emit the result as # ::warning file=...,line=... annotations. # fail-on: off => advisory only, does not redden the build; change to error for a gate. + # The Action runs the bundle it ships, so nothing has to be installed first. - name: Index review + id: index-review uses: JingYu-create520/sql-index-advisor@v0 with: path: src/main/resources/mapper @@ -41,9 +43,10 @@ jobs: path: sia-report.json if-no-files-found: ignore - # Optional: hand the DBA a reviewable migration file directly. + # Optional: hand the DBA a reviewable migration file, using the same CLI the + # Action ran (its `cli` output), so this step cannot drift to another version. - name: Emit migration SQL run: | - sia src/main/resources/mapper \ + ${{ steps.index-review.outputs.cli }} src/main/resources/mapper \ --emit-sql sia-migrations.sql --format json > /dev/null || true cat sia-migrations.sql || true diff --git a/examples/pr-demo/OrderSearchDao.xml b/examples/pr-demo/OrderSearchDao.xml index 292f619..22732ed 100644 --- a/examples/pr-demo/OrderSearchDao.xml +++ b/examples/pr-demo/OrderSearchDao.xml @@ -38,4 +38,12 @@ LIMIT 120000, 20 + + + diff --git a/package.json b/package.json index aab8843..74e8b75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql-index-advisor", - "version": "0.1.6", + "version": "0.1.7", "description": "Offline index advisor for MySQL / MyBatis: slow query log in, index recommendations + migration SQL out.", "keywords": [ "mysql",