From 4da274400c737f680cc0c5be6f045a80a3b50613 Mon Sep 17 00:00:00 2001 From: Michal Pokrywka Date: Fri, 6 Nov 2026 12:34:03 +0100 Subject: [PATCH] chore: replace unmaintained proc-macro-error, harden scripts/github_release.sh --- Cargo.lock | 35 ---- crates/vertigo-macro/Cargo.toml | 1 - crates/vertigo-macro/build.rs | 19 +++ crates/vertigo-macro/src/diagnostics.rs | 159 ++++++++++++++++++ crates/vertigo-macro/src/lib.rs | 131 ++++++++------- crates/vertigo-macro/src/main_wrap.rs | 2 +- .../src/trace_tailwind/bundle.rs | 18 +- .../src/trace_tailwind/macro_impl.rs | 1 - .../src/trace_tailwind/validate.rs | 1 - docs/CHANGELOG.md | 11 ++ scripts/github_release.sh | 77 +++++++-- tsconfig.json | 1 + 12 files changed, 328 insertions(+), 128 deletions(-) create mode 100644 crates/vertigo-macro/src/diagnostics.rs diff --git a/Cargo.lock b/Cargo.lock index d7798f1bf..f6d2fce38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2867,30 +2867,6 @@ dependencies = [ "syn 3.0.9", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -3618,16 +3594,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.119" @@ -4325,7 +4291,6 @@ dependencies = [ "pkg-version", "pretty_assertions", "prettyplease", - "proc-macro-error", "proc-macro2", "quote", "rstml", diff --git a/crates/vertigo-macro/Cargo.toml b/crates/vertigo-macro/Cargo.toml index 590cf55f8..5ee310cca 100644 --- a/crates/vertigo-macro/Cargo.toml +++ b/crates/vertigo-macro/Cargo.toml @@ -21,7 +21,6 @@ itertools = "0.15" pest = "2.9" pest_derive = "2.9" pkg-version = "1" -proc-macro-error = "1.0" proc-macro2 = "1.0" quote = "1.0" rstml = "0.13" diff --git a/crates/vertigo-macro/build.rs b/crates/vertigo-macro/build.rs index 73f06ab19..737a6100f 100644 --- a/crates/vertigo-macro/build.rs +++ b/crates/vertigo-macro/build.rs @@ -8,6 +8,7 @@ fn main() { export_var("PROFILE"); probe_default_field_values(); + probe_proc_macro_diagnostic(); // No `rerun-if-*` directive here on purpose: a PROFILE change already yields a // different build-script unit, and emitting any of them would narrow cargo from @@ -49,6 +50,24 @@ fn probe_default_field_values() { } } +/// A macro can warn only through `proc_macro::Diagnostic`, unstable (rust-lang/rust#54140). +/// `vertigo_macro_warnings` turns the macros' warnings on when the compiler has it, elsewhere +/// they're dropped. +fn probe_proc_macro_diagnostic() { + println!("cargo:rustc-check-cfg=cfg(vertigo_macro_warnings)"); + + const PROBE: &str = "#![feature(proc_macro_diagnostic)] +extern crate proc_macro; +pub fn f(span: proc_macro::Span) { + proc_macro::Diagnostic::spanned(span, proc_macro::Level::Warning, \"\").emit(); +} +"; + + if compiles("diagnostic", PROBE) { + println!("cargo:rustc-cfg=vertigo_macro_warnings"); + } +} + /// Whether the compiler building this crate builds `source` as a library. fn compiles(name: &str, source: &str) -> bool { let (Some(rustc), Some(out_dir)) = (env::var_os("RUSTC"), env::var_os("OUT_DIR")) else { diff --git a/crates/vertigo-macro/src/diagnostics.rs b/crates/vertigo-macro/src/diagnostics.rs new file mode 100644 index 000000000..b26fc923b --- /dev/null +++ b/crates/vertigo-macro/src/diagnostics.rs @@ -0,0 +1,159 @@ +//! Errors and warnings the macros report while they expand. +//! +//! A macro reports any number of errors with [`emit_error!`] and goes on, so the user gets +//! them all at once. [`expand`] runs the macro, and if it reported any, they replace what it +//! made: `compile_error!` invocations pointing at the spans given. +//! +//! [`emit_warning!`] warns only on a compiler with `proc_macro::Diagnostic` (nightly, see +//! `vertigo_macro_warnings` in build.rs) and is dropped elsewhere: rustc has no stable way for +//! a macro to warn. + +use std::cell::RefCell; + +use proc_macro2::{Span, TokenStream as TokenStream2}; + +thread_local! { + static ERRORS: RefCell> = const { RefCell::new(Vec::new()) }; +} + +/// The message of a diagnostic: `format!` arguments, or one value to display. +macro_rules! diagnostic_message { + ($format:expr, $($argument:expr),+ $(,)?) => { + format!($format, $($argument),+) + }; + ($message:expr $(,)?) => { + ::std::string::ToString::to_string(&$message) + }; +} + +/// Report an error at a span (`proc_macro::Span` or `proc_macro2::Span`), with a message as +/// `format!` takes it, or one value to display. +macro_rules! emit_error { + ($span:expr, $($message:tt)+) => { + $crate::diagnostics::error($span, diagnostic_message!($($message)+)) + }; +} + +/// [`emit_error!`] at the macro's call site. +macro_rules! emit_call_site_error { + ($($message:tt)+) => { + emit_error!(::proc_macro2::Span::call_site(), $($message)+) + }; +} + +/// Report a warning, as [`emit_error!`] takes it - on nightly only, see the module docs. +macro_rules! emit_warning { + ($span:expr, $($message:tt)+) => { + $crate::diagnostics::warning($span, diagnostic_message!($($message)+)) + }; +} + +pub(crate) fn error(span: impl Into, message: String) { + ERRORS.with_borrow_mut(|errors| errors.push(syn::Error::new(span.into(), message))); +} + +pub(crate) fn warning(span: impl Into, message: String) { + // Out of a macro, in this crate's tests, there's no compiler to take it + #[cfg(vertigo_macro_warnings)] + if proc_macro::is_available() { + proc_macro::Diagnostic::spanned(span.into().unwrap(), proc_macro::Level::Warning, message) + .emit(); + } + #[cfg(not(vertigo_macro_warnings))] + let _ = (span, message); +} + +/// Run a macro's expansion. If it reported errors, they replace what it made. +pub(crate) fn expand( + expansion: impl FnOnce() -> proc_macro::TokenStream, +) -> proc_macro::TokenStream { + // Left by an expansion that panicked - rustc goes on to the next macro on the same thread + take_errors(); + let output = expansion(); + match errors_to_tokens(take_errors()) { + Some(errors) => errors.into(), + None => output, + } +} + +fn take_errors() -> Vec { + ERRORS.take() +} + +fn errors_to_tokens(errors: Vec) -> Option { + if errors.is_empty() { + return None; + } + Some(errors.iter().map(syn::Error::to_compile_error).collect()) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn messages() -> Vec { + take_errors().iter().map(ToString::to_string).collect() + } + + #[test] + fn message_forms() { + take_errors(); + let name = "x"; + let owned = String::from("from a value"); + + emit_error!(Span::call_site(), "plain"); + emit_error!(Span::call_site(), "formatted {} {:?}", name, 1); + emit_error!(Span::call_site(), "trailing comma {}", name,); + emit_error!(Span::call_site(), owned); + emit_call_site_error!("at call site {}", name); + + assert_eq!( + messages(), + [ + "plain", + "formatted x 1", + "trailing comma x", + "from a value", + "at call site x" + ] + ); + } + + #[test] + fn a_value_is_displayed_not_formatted() { + take_errors(); + let message = "{not an argument}"; + + emit_error!(Span::call_site(), message); + + assert_eq!(messages(), ["{not an argument}"]); + } + + #[test] + fn warnings_are_not_errors() { + take_errors(); + + emit_warning!(Span::call_site(), "a warning {}", 1); + + assert!(take_errors().is_empty()); + } + + #[test] + fn errors_become_compile_errors() { + assert!(errors_to_tokens(Vec::new()).is_none()); + + let errors = vec![ + syn::Error::new(Span::call_site(), "first"), + syn::Error::new(Span::call_site(), "second"), + ]; + let tokens = errors_to_tokens(errors).map(|tokens| tokens.to_string()); + + assert_eq!( + tokens.as_deref(), + Some( + ":: core :: compile_error ! { \"first\" } \ + :: core :: compile_error ! { \"second\" }" + ) + ); + } +} diff --git a/crates/vertigo-macro/src/lib.rs b/crates/vertigo-macro/src/lib.rs index 538fb4d8f..2c783778f 100644 --- a/crates/vertigo-macro/src/lib.rs +++ b/crates/vertigo-macro/src/lib.rs @@ -2,11 +2,14 @@ // see `probe_default_field_values` in build.rs. #![cfg_attr(vertigo_default_props_unstable, feature(allow_internal_unstable))] #![cfg_attr(vertigo_default_props_unstable, allow(internal_features))] +// Warnings from the macros, see `probe_proc_macro_diagnostic` in build.rs. +#![cfg_attr(vertigo_macro_warnings, feature(proc_macro_diagnostic))] #[macro_use] extern crate pest_derive; +// First, so its macros are in scope in the modules below #[macro_use] -extern crate proc_macro_error; +mod diagnostics; mod bind; mod component; @@ -38,125 +41,124 @@ use crate::{ }; #[proc_macro] -#[proc_macro_error] pub fn dom(input: TokenStream) -> TokenStream { - with_build_tracking(|| dom_inner(input)).into() + diagnostics::expand(|| with_build_tracking(|| dom_inner(input)).into()) } #[proc_macro] -#[proc_macro_error] pub fn dom_element(input: TokenStream) -> TokenStream { - with_build_tracking(|| dom_element_inner(input)).into() + diagnostics::expand(|| with_build_tracking(|| dom_element_inner(input)).into()) } #[proc_macro] -#[proc_macro_error] pub fn dom_debug(input: TokenStream) -> TokenStream { - let stream = with_build_tracking(|| dom_inner(input)); - emit_warning!("debug: {:?}", stream); - stream.into() + diagnostics::expand(|| { + let stream = with_build_tracking(|| dom_inner(input)); + emit_warning!(proc_macro2::Span::call_site(), "debug: {}", stream); + stream.into() + }) } #[proc_macro] -#[proc_macro_error] pub fn css_block(input: TokenStream) -> TokenStream { - let (css_str, _, refs) = generate_css_string(input); - let result = quote! {{ - #refs - #css_str - }}; - result.into() + diagnostics::expand(|| { + let (css_str, _, refs) = generate_css_string(input); + let result = quote! {{ + #refs + #css_str + }}; + result.into() + }) } #[proc_macro] -#[proc_macro_error] pub fn css(input: TokenStream) -> TokenStream { - let (css_str, is_dynamic, refs) = generate_css_string(input); - - let result = if is_dynamic { - quote! {{ - #refs - vertigo::Css::string(#css_str) - }} - } else { - quote! { - vertigo::Css::str(#css_str) - } - }; - result.into() + diagnostics::expand(|| { + let (css_str, is_dynamic, refs) = generate_css_string(input); + + let result = if is_dynamic { + quote! {{ + #refs + vertigo::Css::string(#css_str) + }} + } else { + quote! { + vertigo::Css::str(#css_str) + } + }; + result.into() + }) } #[proc_macro_derive(AutoJsJson, attributes(js_json))] -#[proc_macro_error] pub fn auto_js_json(input: TokenStream) -> TokenStream { - let Ok(ast) = syn::parse(input) else { - emit_call_site_error!("Failed to parse input"); - return quote! {}.into(); - }; - - match jsjson::impl_js_json_derive(&ast) { - Ok(result) => result, - Err(message) => { - emit_call_site_error!("{}", message); + diagnostics::expand(|| { + let Ok(ast) = syn::parse(input) else { + emit_call_site_error!("Failed to parse input"); return quote! {}.into(); + }; + + match jsjson::impl_js_json_derive(&ast) { + Ok(result) => result, + Err(message) => { + emit_call_site_error!("{}", message); + quote! {}.into() + } } - } + }) } #[proc_macro] -#[proc_macro_error] pub fn tw(input: TokenStream) -> TokenStream { - with_build_tracking(|| match trace_tailwind(input) { - Ok(token_stream) => token_stream, - Err(err) => abort_call_site!(err), + diagnostics::expand(|| { + with_build_tracking(|| match trace_tailwind(input) { + Ok(token_stream) => token_stream, + Err(err) => { + emit_call_site_error!(err); + proc_macro2::TokenStream::new() + } + }) + .into() }) - .into() } #[proc_macro] -#[proc_macro_error] pub fn include_static(input: TokenStream) -> TokenStream { - include_static_inner(input) + diagnostics::expand(|| include_static_inner(input)) } #[proc_macro] -#[proc_macro_error] pub fn bind(input: TokenStream) -> TokenStream { - convert_to_tokens(bind_inner(input.into())) + diagnostics::expand(|| convert_to_tokens(bind_inner(input.into()))) } #[proc_macro] -#[proc_macro_error] pub fn bind_spawn(input: TokenStream) -> TokenStream { - convert_to_tokens(bind_spawn_inner(input.into())) + diagnostics::expand(|| convert_to_tokens(bind_spawn_inner(input.into()))) } #[proc_macro] -#[proc_macro_error] pub fn bind_rc(input: TokenStream) -> TokenStream { - convert_to_tokens(bind_rc_inner(input.into())) + diagnostics::expand(|| convert_to_tokens(bind_rc_inner(input.into()))) } #[proc_macro_attribute] -#[proc_macro_error] pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream { - main_wrap(input) + diagnostics::expand(|| main_wrap(input)) } #[proc_macro_attribute] -#[proc_macro_error] #[cfg_attr( vertigo_default_props_unstable, allow_internal_unstable(default_field_values) )] pub fn component(attrs: TokenStream, input: TokenStream) -> TokenStream { - component_inner(attrs, input) + diagnostics::expand(|| component_inner(attrs, input)) } #[proc_macro] -#[proc_macro_error] pub fn js_inner(input: TokenStream) -> TokenStream { - js_expression(input) + diagnostics::expand(|| js_expression(input)) } fn convert_to_tokens(input: Option) -> TokenStream { @@ -167,9 +169,10 @@ fn convert_to_tokens(input: Option) -> TokenStream { } #[proc_macro_attribute] -#[proc_macro_error] pub fn store(attr: TokenStream, item: TokenStream) -> TokenStream { - store_inner(attr.into(), item.into()) - .unwrap_or_else(|err| err.to_compile_error()) - .into() + diagnostics::expand(|| { + store_inner(attr.into(), item.into()) + .unwrap_or_else(|err| err.to_compile_error()) + .into() + }) } diff --git a/crates/vertigo-macro/src/main_wrap.rs b/crates/vertigo-macro/src/main_wrap.rs index fce7fc90c..dcc7dc6bb 100644 --- a/crates/vertigo-macro/src/main_wrap.rs +++ b/crates/vertigo-macro/src/main_wrap.rs @@ -12,7 +12,7 @@ pub(crate) fn main_wrap(input: TokenStream) -> TokenStream { // Emit warnings outside of find_warnings_in_stream function for easier testing for (span, msg) in &warnings { - proc_macro_error::emit_warning!(span, msg); + emit_warning!(*span, msg); } let ast = syn::parse_macro_input!(input as syn::ItemFn); diff --git a/crates/vertigo-macro/src/trace_tailwind/bundle.rs b/crates/vertigo-macro/src/trace_tailwind/bundle.rs index 12e61d2e6..16b6c7cc8 100644 --- a/crates/vertigo-macro/src/trace_tailwind/bundle.rs +++ b/crates/vertigo-macro/src/trace_tailwind/bundle.rs @@ -1,5 +1,4 @@ use proc_macro::Span; -use proc_macro_error::{abort_call_site, emit_error}; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use std::error::Error; @@ -85,10 +84,11 @@ fn run_external_tailwind() -> Result> { { Ok(cmd) => cmd, Err(err) => { - abort_call_site!( - "Failed to run external tailwind: {}", err; - help = "Path was: {}", tailwind_executable_abs.display() - ); + return Err(format!( + "Failed to run external tailwind: {err}\n\n = help: Path was: {}", + tailwind_executable_abs.display() + ) + .into()); } }; @@ -98,9 +98,9 @@ fn run_external_tailwind() -> Result> { Ok(output.into_owned()) } else { let err_output = String::from_utf8_lossy(&command.stderr); - abort_call_site!( - "Tailwind run failed: {}", err_output; - note = "Tailwind output: {}", output; - ); + Err( + format!("Tailwind run failed: {err_output}\n\n = note: Tailwind output: {output}") + .into(), + ) } } diff --git a/crates/vertigo-macro/src/trace_tailwind/macro_impl.rs b/crates/vertigo-macro/src/trace_tailwind/macro_impl.rs index d53540baa..c989a24e2 100644 --- a/crates/vertigo-macro/src/trace_tailwind/macro_impl.rs +++ b/crates/vertigo-macro/src/trace_tailwind/macro_impl.rs @@ -1,5 +1,4 @@ use proc_macro::TokenStream; -use proc_macro_error::emit_error; use proc_macro2::TokenStream as TokenStream2; use quote::{ToTokens, quote}; use std::cell::Cell; diff --git a/crates/vertigo-macro/src/trace_tailwind/validate.rs b/crates/vertigo-macro/src/trace_tailwind/validate.rs index fe9294bc7..f6c05fc14 100644 --- a/crates/vertigo-macro/src/trace_tailwind/validate.rs +++ b/crates/vertigo-macro/src/trace_tailwind/validate.rs @@ -1,5 +1,4 @@ use crate::trace_tailwind::paths::get_tailwind_classes_file_path; -use proc_macro_error::emit_error; use std::error::Error; pub(crate) fn validate_tailwind_classes(bundle: &str) -> Result<(), Box> { diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index b73000307..701ee4b99 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,17 @@ +## Unreleased + +### Fixed + +* On nightly, an error from a macro came with follow-up errors from the code it made anyway. + +### Internals + +* The macros report errors and warnings without proc-macro-error (unmaintained, + RUSTSEC-2024-0370), so an app no longer builds syn 1. + ## 0.14.3 - 2026-11-06 ### Added diff --git a/scripts/github_release.sh b/scripts/github_release.sh index 088d556ae..f05c865e9 100755 --- a/scripts/github_release.sh +++ b/scripts/github_release.sh @@ -1,22 +1,23 @@ #!/usr/bin/env bash -# Tags HEAD and creates a GitHub release from the newest docs/CHANGELOG.md entry. +# Tags HEAD and creates a GitHub release from the newest changelog entry. # Without arguments prints the usage. set -euo pipefail -CHANGELOG=docs/CHANGELOG.md +# The changelog is the first of these found +CHANGELOGS=(docs/CHANGELOG.md CHANGELOG.md CHANGES.md) usage() { cat << EOF Usage: $0 --dry-run | --release -Tags HEAD with the version of the newest $CHANGELOG entry, pushes the tag and creates +Tags HEAD with the version of the newest changelog entry, pushes the tag and creates a GitHub release from the entry: tag vX.Y.Z, title "X.Y.Z - YYYY-MM-DD" (the heading), -the entry as the notes. +the entry as the notes. The changelog is the first found of: ${CHANGELOGS[*]}. Run from the main directory of the repository, on master, after the "Prepared X.Y.Z" commit -is pushed. +is pushed. A run stopped after pushing the tag can be run again: a tag on HEAD is kept. --dry-run print the tag, title and notes, and the checks that would fail, change nothing --release tag, push the tag and create the release (asks first) @@ -50,6 +51,18 @@ fail() { FAILED=1 } +CHANGELOG= +for CANDIDATE in "${CHANGELOGS[@]}"; do + if [ -f "$CANDIDATE" ]; then + CHANGELOG=$CANDIDATE + break + fi +done +if [ -z "$CHANGELOG" ]; then + echo "Error: no changelog here (${CHANGELOGS[*]}), run from the main directory of the repository" >&2 + exit 1 +fi + # The first "## " heading and the lines up to the next one, without blank lines around TITLE=$(grep -m1 '^## ' "$CHANGELOG" | sed 's/^## //') NOTES=$(awk ' @@ -78,8 +91,9 @@ if [ "$CARGO_VERSION" != "$VERSION" ]; then fail "Cargo.toml has version $CARGO_VERSION, $CHANGELOG $VERSION" fi -if ! gh auth status > /dev/null 2>&1; then - fail "gh isn't installed or logged in (gh auth login)" +# Not `gh auth status`: it passes with a revoked or expired token +if [ "$(gh api 'repos/{owner}/{repo}' --jq .permissions.push 2> /dev/null)" != "true" ]; then + fail "gh can't push to the repository: not installed, not logged in, bad credentials or no access (gh auth login)" fi if [ -n "$(git status --porcelain)" ]; then @@ -91,16 +105,36 @@ if ! git merge-base --is-ancestor HEAD origin/master; then fail "HEAD ($(git log -1 --format='%h %s')) isn't on origin/master" fi -if git rev-parse --quiet --verify "refs/tags/$TAG" > /dev/null; then - fail "tag $TAG exists already" +# A tag on HEAD is left from a run that stopped before the release, one elsewhere stops it +HEAD_COMMIT=$(git rev-parse HEAD) +LOCAL_TAG=$(git rev-parse --quiet --verify "refs/tags/$TAG^{commit}" || true) +if [ -n "$LOCAL_TAG" ] && [ "$LOCAL_TAG" != "$HEAD_COMMIT" ]; then + fail "tag $TAG exists already, on $(git log -1 --format='%h %s' "$LOCAL_TAG")" +fi +# An annotated tag comes with a `^{}` line giving the commit it points to +REMOTE_TAG=$(git ls-remote --tags origin "refs/tags/$TAG" "refs/tags/$TAG^{}" | awk -v ref="refs/tags/$TAG" ' + $2 == ref { tag = $1 } + $2 == ref "^{}" { peeled = $1 } + END { print peeled ? peeled : tag } +') +if [ -n "$REMOTE_TAG" ] && [ "$REMOTE_TAG" != "$HEAD_COMMIT" ]; then + fail "tag $TAG exists on origin already, on ${REMOTE_TAG:0:8}" fi -if git ls-remote --exit-code --tags origin "refs/tags/$TAG" > /dev/null; then - fail "tag $TAG exists on origin already" + +if gh release view "$TAG" > /dev/null 2>&1; then + fail "release $TAG exists already" fi -echo "Tag: $TAG -> $(git log -1 --format='%h %s')" +if [ "$REMOTE_TAG" = "$HEAD_COMMIT" ]; then + TAG_STATE=" (pushed already)" +elif [ "$LOCAL_TAG" = "$HEAD_COMMIT" ]; then + TAG_STATE=" (tagged already, not pushed)" +else + TAG_STATE= +fi +echo "Tag: $TAG -> $(git log -1 --format='%h %s')$TAG_STATE" echo "Title: $TITLE" -echo "Notes:" +echo "Notes: from $CHANGELOG" echo echo "$NOTES" echo @@ -114,12 +148,23 @@ if [ -n "$DRY_RUN" ]; then exit 0 fi -read -r -p "Push tag $TAG and publish the release? [y/N] " ANSWER +if [ -n "$REMOTE_TAG" ]; then + QUESTION="Publish the release?" +else + QUESTION="Push tag $TAG and publish the release?" +fi +read -r -p "$QUESTION [y/N] " ANSWER if [ "$ANSWER" != "y" ] && [ "$ANSWER" != "Y" ]; then echo "Aborted." exit 1 fi -git tag "$TAG" -git push origin "$TAG" +# Only the tag that gets pushed is made locally: a lightweight copy of an annotated tag +# on origin would clash with it on the next fetch +if [ -z "$REMOTE_TAG" ]; then + if [ -z "$LOCAL_TAG" ]; then + git tag "$TAG" + fi + git push origin "$TAG" +fi gh release create "$TAG" --verify-tag --title "$TITLE" --notes-file - <<< "$NOTES" diff --git a/tsconfig.json b/tsconfig.json index d304ea497..ba691e557 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,5 @@ { + "include": ["crates/vertigo/src/driver_module/src_js"], "compileOnSave": false, "compilerOptions": { "target": "es2020",