Release v0.7.0#22
Merged
Merged
Conversation
Two related gaps in the CLI that make it impossible to do an in-place
database swap on a saved card, or to set up a Slack alert that the
Metabase v0.59+ notification API actually accepts.
## question update --db <id>
The CLI exposed --name, --sql, --display, etc. on `question update`, but
not a way to change the underlying database. Setting only the top-level
database_id via PUT /api/card/{id} leaves dataset_query.database
pointing at the original DB, so the card keeps running against the old
source even after the update succeeds. New flag updates both fields so
they stay consistent. Factored out applyDatabaseToDatasetQuery as a
pure helper with regression tests covering v0.59+ stages and legacy
native shapes.
## Slack alerts / notifications
Three coupled bugs that together made `--channel-type slack`
unsupported on Metabase v0.59+:
1. channel_type was sent as the bare "slack"/"email" string. v0.59+
requires the "channel/" prefix; the bare form fails with
`{"specific-errors":{"handlers":[{"channel_type":
["unknown error, received: :slack"]}]}}`. The new
canonicalizeChannelType helper accepts both forms and emits the
prefixed one.
2. recipients only supported user-id targets (always emitting
`notification-recipient/user`). Slack channel-name targets need a
`notification-recipient/raw-value` recipient with
`details.value: "#channel"`. Added --slack-channel <name> on
`alert create`, `alert update`, and `notification create`, and
surfaced helpers (slackChannelRecipient, userRecipient,
cronSubscription) on the API module so library users can compose
handlers correctly too.
3. Schedule was attached to handlers[].schedule. v0.59+ moved
scheduling to top-level subscriptions[] as
`notification-subscription/cron` with a cron_schedule string.
translateChannelsToSubscriptions converts both the legacy
schedule_type/schedule_hour cadence and a new --schedule <cron>
flag to the new shape; the legacy form is translated to Quartz
cron internally for back-compat.
Also renamed the payload fields the API now expects:
alert_condition + alert_above_goal -> send_condition (has_result /
goal_above / goal_below), alert_first_only -> send_once. Both legacy
field names still work as CLI input; the translation happens inside
AlertApi.
## Verified end-to-end
- `metabase-cli question update 24355 --db 35 --unsafe` now updates
database_id AND dataset_query.database in one PUT; the card is
immediately runnable against the new DB.
- `metabase-cli alert create --card 24355 --condition rows
--channel-type slack --slack-channel "#nsdc-assessment-alert"
--schedule "0 0 * * * ?"` creates alert #58 against
v0.59.4 (d4fb593), with the v0.59+ canonical body:
handlers: [{
channel_type: "channel/slack",
recipients: [{
type: "notification-recipient/raw-value",
details: { value: "#nsdc-assessment-alert" }
}]
}],
subscriptions: [{
type: "notification-subscription/cron",
cron_schedule: "0 0 * * * ?"
}],
payload: { send_condition: "has_result", send_once: false }
## Tests
Full suite stays green: 142 passing (138 baseline + 4 new). New
coverage: applyDatabaseToDatasetQuery on v0.59+ stages and legacy
native shapes, and an AlertApi.create regression that asserts
channel/slack + raw-value recipient + top-level cron subscription on
the outgoing body.
Two review follow-ups on the v0.59+ alert work: - alert create: canonicalize --channel-type before the Slack-recipient guard so the prefixed form (channel/slack) is validated the same as the bare form (slack). Previously the guard was skipped for the prefixed form and an empty-recipient Slack handler was sent. - AlertApi.update: when only --above-goal is supplied (no --condition), imply a goal condition instead of falling back to rows/has_result, which silently downgraded a goal alert. Adds regression tests for both, plus canonicalizeChannelType idempotency.
…vitest) - brace-expansion: bump transitive dep past GHSA-f886-m6hf-6m8v / GHSA-jxxr-4gwj-5jf2 (ReDoS / DoS) via npm audit fix. - postcss: bump past GHSA-qx2v-qp2m-jg93 (<8.5.10 XSS in stringify). - vitest: 3.2.4 -> 4.1.8, clearing the critical GHSA-5xrq-8626-4rwp (UI-server arbitrary file read/exec). Dev-only; full suite still green under vitest 4. npm audit now reports 0 vulnerabilities.
…-slack-alerts feat: question update --db; fix Slack alerts/notifications for v0.59+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v0.7.0.
Included
question update --db; Slack alerts/notifications for Metabase v0.59+ (canonicalchannel/slack,--slack-channelraw-value recipients, top-level cronsubscriptions[],send_condition/send_oncerenames).--channel-typebefore the Slack-recipient guard;alert update --above-goalalone now implies a goal condition.npm auditadvisories (dev deps):brace-expansion(ReDoS),postcss(XSS),vitest3→4.1.8 (critical).npm auditnow reports 0 vulnerabilities.Verification
npm run typecheck✅npm test✅ 145 passingnpm run build✅npm audit✅ 0 vulnerabilitiesVersion bumped to 0.7.0 (package.json + package-lock.json); CHANGELOG finalized under
[0.7.0] - 2026-06-02.