cloudcli-taskwork-public/scripts/export-patches.sh

50 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Regenerates plugin-taskwork/patches/*.patch from the fork's feature branches.
#
# The branches in cloudcli/ are the single source of truth (SPEC-v3 §12.0);
# the .patch files are a derived artefact and are never edited by hand.
#
# Usage: ./scripts/export-patches.sh [base-tag]
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BASE_TAG="${1:-v1.37.2}"
SRC="$ROOT/cloudcli"
OUT="$ROOT/plugin-taskwork/patches"
# branch:output-file — the numeric prefix mirrors the publication order (§12.4),
# not a dependency: every patch applies to the base tag on its own.
BRANCHES=(
"feat/resizable-sidebar:0001-feat-resizable-sidebar.patch"
"feat/plugin-host-api:0002-feat-plugin-host-api.patch"
"feat/plugin-sidebar-surface:0003-feat-plugin-sidebar-surface.patch"
)
[ -d "$SRC/.git" ] || { echo "cloudcli/ submodule is not initialised — run ./scripts/bootstrap.sh" >&2; exit 1; }
[ -d "$OUT" ] || { echo "plugin-taskwork/patches/ is missing — run ./scripts/bootstrap.sh" >&2; exit 1; }
git -C "$SRC" rev-parse --verify --quiet "$BASE_TAG^{commit}" >/dev/null \
|| { echo "base tag $BASE_TAG not found in cloudcli/ (git fetch upstream --tags)" >&2; exit 1; }
for entry in "${BRANCHES[@]}"; do
branch="${entry%%:*}"
file="${entry##*:}"
if ! git -C "$SRC" rev-parse --verify --quiet "$branch" >/dev/null; then
echo "skip $branch (branch does not exist yet)"
continue
fi
# Independence check: a feature branch must sit directly on the base tag,
# otherwise its patch would silently carry another PR's commits (§4.4).
base="$(git -C "$SRC" merge-base "$BASE_TAG" "$branch")"
if [ "$base" != "$(git -C "$SRC" rev-parse "$BASE_TAG^{commit}")" ]; then
echo "ERROR: $branch is not based on $BASE_TAG" >&2
exit 1
fi
git -C "$SRC" format-patch "$BASE_TAG..$branch" --stdout > "$OUT/$file"
commits="$(git -C "$SRC" rev-list --count "$BASE_TAG..$branch")"
echo "wrote patches/$file ($commits commit(s))"
done