postit-debian: support POSTIT_GIT_TAG as a tag (not just a branch)
The previous override_dh_auto_build used 'git clone --branch <tag>' which only accepts branch names. Feeding it 1.0.1-rc02 (a tag, not yet pushed to origin) failed with 'La branche distante 1.0.1-rc02 n'a pas ete trouvee' and aborted the package build. Switch to a 'git init + remote add + fetch --depth=1 origin <ref> + checkout FETCH_HEAD' sequence, which works for both branches and tags, including local-only tags fetched via file:// (the typical RC-staging workflow: 'git tag' on the local checkout, then 'make POSTIT_GIT_URL=file:///... POSTIT_GIT_TAG=<tag>' before pushing). The fetch error now carries a diagnostic that points the operator at the file:// override and at the missing 'git push'. Adds tests/test-fetch-upstream.sh with four cases against the real pazof/yavsc remote and a synthetic local repo: tag on GitHub, branch on GitHub, .git reuse, and tag via file://. Wired into 'make test'.
This commit is contained in:
parent
69ec916c4e
commit
7f57952a92
3 changed files with 202 additions and 8 deletions
10
Makefile
10
Makefile
|
|
@ -4,6 +4,11 @@
|
|||
# make deb : build a .deb in the parent directory (or
|
||||
# $POSTIT_OUT_DIR if set). Equivalent to
|
||||
# dpkg-buildpackage -us -uc -b.
|
||||
# make test : run the non-regression tests under tests/.
|
||||
# The fetch test pins the upstream Git mechanics
|
||||
# that previously regressed on tag-vs-branch
|
||||
# handling (1.0.1-rc02). Set SKIP_NETWORK_TESTS=1
|
||||
# to skip the GitHub-egress parts.
|
||||
# make clean : rm -rf build/ and the per-package staging tree
|
||||
# under debian/postit.
|
||||
# make source : fetch the upstream yavsc source tree under
|
||||
|
|
@ -21,7 +26,7 @@ POSTIT_GIT_TAG ?= 1.0.0
|
|||
POSTIT_RUNTIME ?= linux-x64
|
||||
POSTIT_OUT_DIR ?= $(CURDIR)/..
|
||||
|
||||
.PHONY: deb clean source
|
||||
.PHONY: deb clean source test
|
||||
|
||||
deb:
|
||||
@echo " POSTIT_GIT_TAG=$(POSTIT_GIT_TAG) POSTIT_RUNTIME=$(POSTIT_RUNTIME) POSTIT_GIT_URL=$(POSTIT_GIT_URL)"
|
||||
|
|
@ -49,3 +54,6 @@ source:
|
|||
mkdir -p build
|
||||
git clone --depth=1 --branch $(POSTIT_GIT_TAG) \
|
||||
$(POSTIT_GIT_URL) build/yavsc-src
|
||||
|
||||
test:
|
||||
@bash tests/test-fetch-upstream.sh
|
||||
|
|
|
|||
31
debian/rules
vendored
31
debian/rules
vendored
|
|
@ -55,15 +55,32 @@ override_dh_auto_build:
|
|||
sed 's/@VERSION@/$(POSTIT_GIT_TAG)/g' \
|
||||
$(CURDIR)/debian/changelog.in > $(CURDIR)/debian/changelog; \
|
||||
fi
|
||||
# 1. Fetch the upstream source.
|
||||
# 1. Fetch the upstream source at POSTIT_GIT_TAG. The ref can
|
||||
# be either a branch name (e.g. `main`) or a tag (e.g.
|
||||
# `1.0.1-rc02`); `git fetch origin <ref>` handles both. The
|
||||
# reference MUST exist on the configured POSTIT_GIT_URL
|
||||
# remote (default: github.com/pazof/yavsc). If you are
|
||||
# building from a tag that is only on your local clone
|
||||
# (typical right after `git tag 1.0.1-rc02` and before
|
||||
# `git push origin 1.0.1-rc02`), point POSTIT_GIT_URL at
|
||||
# your local checkout:
|
||||
# make POSTIT_GIT_URL=file:///home/paul/Workspace/yavsc \
|
||||
# POSTIT_GIT_TAG=1.0.1-rc02
|
||||
mkdir -p $(POSTIT_BUILD_DIR)
|
||||
if [ -d $(POSTIT_SRC_DIR) ]; then \
|
||||
git -C $(POSTIT_SRC_DIR) fetch --depth=1 origin $(POSTIT_GIT_TAG); \
|
||||
git -C $(POSTIT_SRC_DIR) reset --hard $(POSTIT_GIT_TAG); \
|
||||
else \
|
||||
git clone --depth=1 --branch $(POSTIT_GIT_TAG) \
|
||||
$(POSTIT_GIT_URL) $(POSTIT_SRC_DIR); \
|
||||
if [ ! -d $(POSTIT_SRC_DIR)/.git ]; then \
|
||||
git init -q $(POSTIT_SRC_DIR); \
|
||||
git -C $(POSTIT_SRC_DIR) remote add origin $(POSTIT_GIT_URL); \
|
||||
fi
|
||||
if ! git -C $(POSTIT_SRC_DIR) fetch --depth=1 origin $(POSTIT_GIT_TAG); then \
|
||||
echo "" >&2; \
|
||||
echo " ERROR: POSTIT_GIT_TAG='$(POSTIT_GIT_TAG)' is not reachable from POSTIT_GIT_URL='$(POSTIT_GIT_URL)'." >&2; \
|
||||
echo " Either push the ref to the remote first (e.g. \`git push origin $(POSTIT_GIT_TAG)\`)" >&2; \
|
||||
echo " or override POSTIT_GIT_URL with a local path that has the ref, e.g." >&2; \
|
||||
echo " make POSTIT_GIT_URL=file:///home/paul/Workspace/yavsc POSTIT_GIT_TAG=$(POSTIT_GIT_TAG)" >&2; \
|
||||
echo "" >&2; \
|
||||
exit 128; \
|
||||
fi
|
||||
git -C $(POSTIT_SRC_DIR) checkout -q FETCH_HEAD
|
||||
|
||||
# 2. Publish PostIt.Desktop for the host architecture.
|
||||
# --self-contained false : rely on the system .NET
|
||||
|
|
|
|||
169
tests/test-fetch-upstream.sh
Executable file
169
tests/test-fetch-upstream.sh
Executable file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Non-regression test for the POSTIT_GIT_TAG handling in debian/rules.
|
||||
#
|
||||
# Background: a previous version of override_dh_auto_build used
|
||||
# `git clone --branch <tag>` to fetch upstream. That only works for
|
||||
# branch names; feeding it an annotated tag (e.g. 1.0.1-rc02) failed
|
||||
# with "La branche distante 1.0.1-rc02 n'a pas ete trouvee" and
|
||||
# aborted the whole package build.
|
||||
#
|
||||
# This test pins the upstream-fetch logic against the *real*
|
||||
# pazof/yavsc remote on GitHub: tags like 1.0.1-rc01 exist there,
|
||||
# so we can verify both branches and tags resolve to the expected
|
||||
# commit without spinning up a fake local server (the local Git
|
||||
# transport handles shallow tag fetches differently from smart-http,
|
||||
# so a local-only test would be misleading).
|
||||
#
|
||||
# Scope: deliberately does NOT run dpkg-buildpackage / dotnet
|
||||
# publish / dh_install. Those stages are exercised manually per
|
||||
# release; this test pins the Git mechanics which previously
|
||||
# regressed silently until the next tag bump.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TEST_NAME="$(basename "$0")"
|
||||
|
||||
# Skip on environments without network access (offline CI runners,
|
||||
# dev sandboxes without GitHub egress). The test is a non-regression
|
||||
# guard, not a connectivity test; failing because GitHub is down
|
||||
# would mask the signal we actually care about.
|
||||
if [ "${SKIP_NETWORK_TESTS:-0}" = "1" ]; then
|
||||
echo "$TEST_NAME: SKIP -- SKIP_NETWORK_TESTS=1"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
WORK="$(mktemp -d -t postit-fetch-test.XXXXXX)"
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
|
||||
# Real remote. The branch + tag values below MUST exist for the
|
||||
# test to pass; if pazof retags the repo, bump them. Anchored on
|
||||
# commits known to be immutable: 1.0.0 is the initial release,
|
||||
# 1.0.1-rc01 is the rc Paul shipped after the OIDC fixes.
|
||||
REMOTE_URL="https://github.com/pazof/yavsc.git"
|
||||
TEST_BRANCH="main"
|
||||
TEST_TAG="1.0.1-rc01"
|
||||
|
||||
# Expected commits from `git ls-remote`. Computed at test time so we
|
||||
# don't have to update this script every time the repo moves; we
|
||||
# just assert "whatever HEAD I end up on must match what `git
|
||||
# ls-remote` says the ref points at".
|
||||
EXPECTED_BRANCH_SHA="$(git ls-remote "$REMOTE_URL" "refs/heads/$TEST_BRANCH" | awk '{print $1}')"
|
||||
EXPECTED_TAG_SHA="$(git ls-remote "$REMOTE_URL" "refs/tags/$TEST_TAG" | awk '{print $1}')"
|
||||
|
||||
if [ -z "$EXPECTED_BRANCH_SHA" ] || [ -z "$EXPECTED_TAG_SHA" ]; then
|
||||
echo "$TEST_NAME: SKIP -- refs not present on remote (branch=$EXPECTED_BRANCH_SHA tag=$EXPECTED_TAG_SHA)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Helper copied verbatim from debian/rules. If debian/rules drifts,
|
||||
# this copy must drift with it -- that is the point of pinning the
|
||||
# logic in a test.
|
||||
fetch_upstream() {
|
||||
local url="$1" ref="$2" dest="$3"
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
if [ ! -d "$dest/.git" ]; then
|
||||
git init -q "$dest"
|
||||
git -C "$dest" remote add origin "$url"
|
||||
fi
|
||||
git -C "$dest" fetch --depth=1 origin "$ref"
|
||||
git -C "$dest" checkout -q FETCH_HEAD
|
||||
}
|
||||
|
||||
# --- Case 1: POSTIT_GIT_TAG points at an annotated tag. ----------
|
||||
# This is the regression case. Before the fix, this failed with
|
||||
# "La branche distante <tag> n'a pas ete trouvee".
|
||||
DEST="$WORK/yavsc-src-tag"
|
||||
rm -rf "$DEST"
|
||||
if ! fetch_upstream "$REMOTE_URL" "$TEST_TAG" "$DEST" 2> "$WORK/fetch-tag.err"; then
|
||||
echo "$TEST_NAME: FAIL -- fetch_upstream errored on tag '$TEST_TAG'"
|
||||
sed 's/^/ /' "$WORK/fetch-tag.err"
|
||||
exit 1
|
||||
fi
|
||||
GOT="$(git -C "$DEST" rev-parse HEAD)"
|
||||
if [ "$GOT" != "$EXPECTED_TAG_SHA" ]; then
|
||||
echo "$TEST_NAME: FAIL -- tag '$TEST_TAG' resolved to '$GOT', expected '$EXPECTED_TAG_SHA'"
|
||||
exit 1
|
||||
fi
|
||||
# A shallow clone cannot always determine "exact tag match" because
|
||||
# the tag-object might not have been fetched. The commit-hash match
|
||||
# above is the authoritative check; the describe call is a softer
|
||||
# sanity signal that we still log but do not gate on.
|
||||
DESCRIBED="$(git -C "$DEST" describe --tags --exact-match HEAD 2>/dev/null || echo '<not exact>')"
|
||||
echo "$TEST_NAME: tag '$TEST_TAG' -> $GOT (describe: $DESCRIBED)"
|
||||
|
||||
# --- Case 2: POSTIT_GIT_TAG points at a branch. ------------------
|
||||
# Branches must keep working; this is the path the old code was
|
||||
# originally written for and we don't want to break it.
|
||||
DEST="$WORK/yavsc-src-branch"
|
||||
rm -rf "$DEST"
|
||||
if ! fetch_upstream "$REMOTE_URL" "$TEST_BRANCH" "$DEST" 2> "$WORK/fetch-branch.err"; then
|
||||
echo "$TEST_NAME: FAIL -- fetch_upstream errored on branch '$TEST_BRANCH'"
|
||||
sed 's/^/ /' "$WORK/fetch-branch.err"
|
||||
exit 1
|
||||
fi
|
||||
GOT="$(git -C "$DEST" rev-parse HEAD)"
|
||||
if [ "$GOT" != "$EXPECTED_BRANCH_SHA" ]; then
|
||||
echo "$TEST_NAME: FAIL -- branch '$TEST_BRANCH' resolved to '$GOT', expected '$EXPECTED_BRANCH_SHA'"
|
||||
exit 1
|
||||
fi
|
||||
echo "$TEST_NAME: branch '$TEST_BRANCH' -> $GOT"
|
||||
|
||||
# --- Case 3: existing .git directory is reused (the second-build
|
||||
# fast path). The build dir persists across builds, so the helper
|
||||
# must not re-init when .git is already there. We populate the
|
||||
# branch first, then refetch to the tag without nuking the
|
||||
# existing origin remote.
|
||||
DEST="$WORK/yavsc-src-reuse"
|
||||
rm -rf "$DEST"
|
||||
fetch_upstream "$REMOTE_URL" "$TEST_BRANCH" "$DEST" >/dev/null 2>&1
|
||||
ORIG_REMOTE="$(git -C "$DEST" remote get-url origin)"
|
||||
if ! fetch_upstream "$REMOTE_URL" "$TEST_TAG" "$DEST" >/dev/null 2> "$WORK/fetch-reuse.err"; then
|
||||
echo "$TEST_NAME: FAIL -- second fetch on existing .git errored"
|
||||
sed 's/^/ /' "$WORK/fetch-reuse.err"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(git -C "$DEST" remote get-url origin)" != "$ORIG_REMOTE" ]; then
|
||||
echo "$TEST_NAME: FAIL -- remote origin was clobbered on reuse"
|
||||
exit 1
|
||||
fi
|
||||
GOT="$(git -C "$DEST" rev-parse HEAD)"
|
||||
if [ "$GOT" != "$EXPECTED_TAG_SHA" ]; then
|
||||
echo "$TEST_NAME: FAIL -- reuse case tag fetch landed on '$GOT', expected '$EXPECTED_TAG_SHA'"
|
||||
exit 1
|
||||
fi
|
||||
echo "$TEST_NAME: reuse case tag '$TEST_TAG' -> $GOT (remote preserved)"
|
||||
|
||||
# --- Case 4: POSTIT_GIT_TAG is a tag that exists only on a local
|
||||
# repo, fetched via file://. This is the Paul workflow for staging
|
||||
# an RC: `git tag 1.0.1-rc02` on ~/Workspace/yavsc, then
|
||||
# `make POSTIT_GIT_URL=file:///home/paul/Workspace/yavsc
|
||||
# POSTIT_GIT_TAG=1.0.1-rc02` to build the .deb before
|
||||
# pushing the tag to github.com/pazof/yavsc. The fix must support
|
||||
# this without requiring the tag to be on a public remote first.
|
||||
LOCAL_REPO="$WORK/local-repo"
|
||||
LOCAL_TAG="test-local-rc-$$"
|
||||
# Use ^{commit} to dereference the tag-object to the underlying
|
||||
# commit; that's what git checkout FETCH_HEAD lands on.
|
||||
LOCAL_TAG_SHA="$(mktemp -u XXXXXXXXXXXX)"
|
||||
git init -q "$LOCAL_REPO"
|
||||
git -C "$LOCAL_REPO" -c user.email=test@test.local -c user.name=test \
|
||||
commit --allow-empty -q -m "local seed"
|
||||
git -C "$LOCAL_REPO" tag -a "$LOCAL_TAG" -m "local-only tag"
|
||||
LOCAL_TAG_SHA="$(git -C "$LOCAL_REPO" rev-parse "$LOCAL_TAG^{commit}")"
|
||||
|
||||
DEST="$WORK/yavsc-src-local"
|
||||
rm -rf "$DEST"
|
||||
if ! fetch_upstream "file://$LOCAL_REPO" "$LOCAL_TAG" "$DEST" 2> "$WORK/fetch-local.err"; then
|
||||
echo "$TEST_NAME: FAIL -- fetch_upstream errored on local-only tag '$LOCAL_TAG'"
|
||||
sed 's/^/ /' "$WORK/fetch-local.err"
|
||||
exit 1
|
||||
fi
|
||||
GOT="$(git -C "$DEST" rev-parse HEAD)"
|
||||
if [ "$GOT" != "$LOCAL_TAG_SHA" ]; then
|
||||
echo "$TEST_NAME: FAIL -- local tag '$LOCAL_TAG' resolved to '$GOT', expected '$LOCAL_TAG_SHA'"
|
||||
exit 1
|
||||
fi
|
||||
echo "$TEST_NAME: local tag '$LOCAL_TAG' via file:// -> $GOT"
|
||||
|
||||
echo "$TEST_NAME: PASS -- tag, branch, reuse, and local-only tag all resolve correctly"
|
||||
Loading…
Add table
Add a link
Reference in a new issue