From f47e3177d4252033db195176d93861a808a77e4e Mon Sep 17 00:00:00 2001 From: Scott Tomaszewski Date: Thu, 4 Jun 2026 12:58:33 -0400 Subject: [PATCH] Updating release recipe to update changelog --- justfile | 65 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/justfile b/justfile index 9cf3428..263031b 100644 --- a/justfile +++ b/justfile @@ -1,22 +1,65 @@ set shell := ["bash", "-c"] +# List available recipes. +default: + @just --list + +# Cut a release: bump the version, promote the changelog, build, commit, push, +# and publish a GitHub release with the plugin assets attached. +# Usage: devbox run release 1.0.1 (or: just release 1.0.1) release version: #!/usr/bin/env bash set -euo pipefail - if [[ `git status --porcelain` ]]; then - echo "Cannot release: 'git status' is not clean. Commit/push or stash changes first" - exit 0 + + # Obsidian versions/tags carry no leading "v". + version="{{version}}" + version="${version#v}" + if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then + echo "Refusing to release: '$version' is not a semver version (e.g. 1.0.1)." + exit 1 fi - npm test - jq '.version = "{{version}}"' manifest.json > tmp && mv tmp manifest.json - jq '.version = "{{version}}"' package.json > tmp && mv tmp package.json - npm run build-no-check - git add . - git commit --allow-empty -am "Prepares for release '{{version}}'" - git push + + if [[ -n "$(git status --porcelain)" ]]; then + echo "Cannot release: working tree is not clean. Commit or stash changes first." + exit 1 + fi + + if git rev-parse "$version" >/dev/null 2>&1; then + echo "Cannot release: tag '$version' already exists." + exit 1 + fi + + # Keep manifest.json, package.json, and versions.json in lockstep. The new + # version maps to the current minAppVersion in versions.json. + min_app_version="$(jq -r '.minAppVersion' manifest.json)" + jq --arg v "$version" '.version = $v' manifest.json > manifest.tmp && mv manifest.tmp manifest.json + jq --arg v "$version" '.version = $v' package.json > package.tmp && mv package.tmp package.json + jq --arg v "$version" --arg m "$min_app_version" '.[$v] = $m' versions.json > versions.tmp && mv versions.tmp versions.json + + # Promote the changelog's "Unreleased" section to this version, then use that + # section's body as the GitHub release notes. + if [[ -f CHANGELOG.md ]] && grep -q '^## Unreleased$' CHANGELOG.md; then + sed -i "s/^## Unreleased$/## $version/" CHANGELOG.md + fi + notes="$(awk -v ver="## $version" '$0==ver{g=1;next} /^## /&&g{exit} g' CHANGELOG.md 2>/dev/null | sed '/^$/d')" + [[ -z "$notes" ]] && notes="Release $version" + + # Produce the release artifact (type-check + tests + bundle to main.js). + npm run build + + git add manifest.json package.json versions.json CHANGELOG.md + git commit --allow-empty -m "Prepares for release '$version'" + git push -u origin HEAD + token="$(just _gh-token)" if [[ -n "$token" ]]; then export GH_TOKEN="$token"; fi - gh release create "{{version}}" --title "{{version}}" --notes "" main.js manifest.json styles.css + + # Tag at the just-pushed commit and attach the assets Obsidian expects. + gh release create "$version" \ + --title "$version" \ + --target "$(git rev-parse --abbrev-ref HEAD)" \ + --notes "$notes" \ + main.js manifest.json styles.css # Echo a GitHub token for `gh`. devbox bundles its own gh (nixpkgs) that can't # read the host keyring where `gh auth login` stored the token, so fall back to