Skip to content

Commit 2b3c181

Browse files
committed
Release 2.9.8: Fix tarball to include all necessary files
- Fixed release tarball generation to include bash completion script, Makefile, source files, and other essential components - Improved tarball generation to use git archive as source of truth, eliminating manual file inventory - Added bash completion information to man page - GitHub workflow plumbing work for new /dist tarball location, Makefile and CI fixes
1 parent 9566df0 commit 2b3c181

File tree

10 files changed

+90
-49
lines changed

10 files changed

+90
-49
lines changed

.github/workflows/release.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ jobs:
2121
uses: actions/checkout@v4
2222
with:
2323
fetch-depth: 0
24+
- name: Fix git ownership for container
25+
run: |
26+
git config --global --add safe.directory "$GITHUB_WORKSPACE"
2427
- name: Verify tag/version consistency
2528
id: ver
2629
run: |
@@ -34,7 +37,7 @@ jobs:
3437
- name: Build
3538
run: |
3639
make clean
37-
make keychain-$(cat VERSION).tar.gz
40+
make dist/keychain-$(cat VERSION).tar.gz
3841
- name: Test space-in-home handling
3942
run: |
4043
ver=$(cat VERSION)
@@ -52,7 +55,7 @@ jobs:
5255
with:
5356
name: keychain-${{ steps.ver.outputs.version }}-artifacts
5457
path: |
55-
keychain-${{ steps.ver.outputs.version }}.tar.gz
58+
dist/keychain-${{ steps.ver.outputs.version }}.tar.gz
5659
keychain
5760
keychain.1
5861
.release-notes.md

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ keychain.txt
77
keychain.spec
88
.specstory/
99
.ci-artifacts*/
10-
/keychain-*.tar.gz
10+
dist/

ChangeLog.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# ChangeLog for Keychain - https://github.com/danielrobbins/keychain
22

3+
## keychain 2.9.8 (2 Nov 2025)
4+
5+
This release fixes the release tarball to include all necessary files for building and using keychain.
6+
7+
Bug fixes:
8+
9+
* Fixed release tarball generation to include bash completion script (`completions/keychain.bash`),
10+
Makefile, source files, and other essential components. Previous release (2.9.7) tarball was
11+
missing these files.
12+
* Improved tarball generation to use `git archive` as source of truth, eliminating manual file
13+
inventory and preventing future omissions.
14+
* Updated release logic to use `dist/` directory for archive generation. GitHub workflow plumbing
15+
work for new `/dist` tarball location, associated `Makefile` and CI fixes.
16+
17+
Documentation:
18+
19+
* Added bash completion information to keychain man page (NOTES section).
20+
321
## keychain 2.9.7 (31 Oct 2025)
422

523
This release fixes critical issues with spaces in HOME directories and usernames, and adds official Git Bash on Windows compatibility.

Makefile

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ Y ?= $(shell date +'%Y')
1111
PREFIX ?= /usr/local
1212
COMPLETIONSDIR ?= $(PREFIX)/share/bash-completion/completions
1313

14-
TARBALL_CONTENTS=keychain README.md ChangeLog.md COPYING.txt MAINTAINERS.txt keychain.pod keychain.1 keychain.spec
15-
1614
all: keychain.1 keychain keychain.spec
1715

1816
.PHONY : tmpclean
@@ -23,10 +21,10 @@ tmpclean:
2321
clean: tmpclean
2422
rm -rf keychain.1 keychain keychain.spec
2523

26-
keychain.spec: keychain.spec.in keychain.sh
24+
keychain.spec: keychain.spec.in keychain.sh VERSION
2725
sed 's/KEYCHAIN_VERSION/$V/' keychain.spec.in > keychain.spec
2826

29-
keychain.1: keychain.pod keychain.sh
27+
keychain.1: keychain.pod keychain.sh VERSION
3028
pod2man --name=keychain --release=$V \
3129
--center='https://github.com/danielrobbins/keychain' \
3230
keychain.pod keychain.1
@@ -61,28 +59,30 @@ keychain: keychain.sh keychain.txt VERSION MAINTAINERS.txt
6159
keychain.txt: keychain.pod
6260
pod2text keychain.pod keychain.txt
6361
64-
keychain-$V.tar.gz: $(TARBALL_CONTENTS)
65-
mkdir keychain-$V
66-
cp $(TARBALL_CONTENTS) keychain-$V
67-
/bin/tar czvf keychain-$V.tar.gz keychain-$V
68-
rm -rf keychain-$V
69-
ls -l keychain-$V.tar.gz
62+
dist/keychain-$V.tar.gz: keychain keychain.1 keychain.spec
63+
mkdir -p dist
64+
rm -rf dist/keychain-$V
65+
git archive --format=tar --prefix=keychain-$V/ HEAD | tar -xf - -C dist/
66+
cp keychain keychain.1 keychain.spec dist/keychain-$V/
67+
tar -C dist -czf dist/keychain-$V.tar.gz keychain-$V
68+
rm -rf dist/keychain-$V
69+
ls -l dist/keychain-$V.tar.gz
7070
7171
# --- Release Automation Helpers ---
7272
.PHONY: release release-refresh
7373
74-
RELEASE_ASSETS=keychain-$V.tar.gz keychain keychain.1
74+
RELEASE_ASSETS=dist/keychain-$V.tar.gz keychain keychain.1
7575
7676
# "release" will orchestrate a tagged release with CI artifact validation & confirmation.
77-
release: $(RELEASE_ASSETS)
77+
release: clean $(RELEASE_ASSETS)
7878
@echo "Orchestrating release $(V)"; \
7979
if [ -z "$$GITHUB_TOKEN" ]; then \
8080
echo "GITHUB_TOKEN not set; export a repo-scoped token to proceed." >&2; exit 1; \
8181
fi; \
8282
./scripts/release-orchestrate.sh create $(V)
8383
8484
# "release-refresh" updates assets of an existing GitHub release (e.g. fixups) with CI validation.
85-
release-refresh: $(RELEASE_ASSETS)
85+
release-refresh: clean $(RELEASE_ASSETS)
8686
@echo "Orchestrating release-refresh $(V)"; \
8787
if [ -z "$$GITHUB_TOKEN" ]; then \
8888
echo "GITHUB_TOKEN not set; export a repo-scoped token to proceed." >&2; exit 1; \

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.9.7
1+
2.9.8

docs/release-steps.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ This document defines the standard release process. Releases use **numeric tags
1717
## 3. Build Artifacts
1818
Manual build (optional; `make release` now auto-rebuilds prerequisites):
1919
```
20-
make clean && make keychain-$(cat VERSION).tar.gz
20+
make clean && make dist/keychain-$(cat VERSION).tar.gz
2121
```
2222
`make release` or `make release-refresh` will ensure these artifacts exist automatically.
2323

@@ -26,7 +26,7 @@ Artifacts:
2626
- `keychain.1` (man page)
2727
- `keychain.spec`
2828
- `keychain.txt`
29-
- `keychain-<version>.tar.gz`
29+
- `dist/keychain-<version>.tar.gz`
3030

3131
## 4. Local Sanity Tests
3232
```
@@ -62,7 +62,7 @@ You will see:
6262
3. Normalized comparison phase (LOCAL vs CI build):
6363
* `keychain` – raw sha256 digest compare.
6464
* `keychain.1` – raw hash first; if different, re-compare with the Pod::Man auto-generated first line stripped. A normalized match counts as a match (header differences ignored).
65-
* `keychain-<version>.tar.gz` – unpack both tarballs; compare sorted file list and per-file sha256 (man page internally also normalized on first line). Blob-level tar/gzip metadata differences (mtime, uid, compression variance) are ignored if internal contents match.
65+
* `dist/keychain-<version>.tar.gz` – unpack both tarballs; compare sorted file list and per-file sha256 (man page internally also normalized on first line). Blob-level tar/gzip metadata differences (mtime, uid, compression variance) are ignored if internal contents match.
6666
Outcome:
6767
- If all artifacts match (raw or normalized) -> Release uses the CI artifact files directly (local artifacts remain untouched for auditing).
6868
- If any real content mismatch exists -> Abort.
@@ -92,7 +92,7 @@ Both require `GITHUB_TOKEN` (repo scope) exported in the environment.
9292
If you forgot something (docs only, same version):
9393
```
9494
# Edit ChangeLog.md (if you need to adjust text; refresh will regenerate release notes from current ChangeLog plus provenance.)
95-
# Rebuild if needed (optional): make keychain-$(cat VERSION).tar.gz
95+
# Rebuild if needed (optional): make dist/keychain-$(cat VERSION).tar.gz
9696
make release-refresh
9797
```
9898
You will again get CI fetch attempt, comparisons, preview, and prompt.
@@ -121,16 +121,16 @@ awk -v ver="$version" '/^## keychain 'ver' /{f=1;print;next} /^## keychain /&&f
121121

122122
## 13. Verification Matrix
123123
| Item | Location | Must Match |
124-
|------|----------|-----------|
124+
|------|----------|------------|
125125
| Version tag | git tag | `VERSION` file |
126126
| Wrapper script | `keychain` | contains version string |
127127
| Man page header | `keychain.1` | version/date/center URL |
128-
| Tarball name | `keychain-<version>.tar.gz` | version |
128+
| Tarball name | `dist/keychain-<version>.tar.gz` | version |
129129

130130
## 14. Minimal Quick Release Recap
131131
```
132132
$EDITOR ChangeLog.md VERSION
133-
make clean && make keychain-$(cat VERSION).tar.gz
133+
make clean && make dist/keychain-$(cat VERSION).tar.gz
134134
./keychain --version
135135
git tag -s $(cat VERSION) -m "$(cat VERSION)"
136136
git push && git push --tags

keychain.pod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,5 +737,11 @@ Keychain was created and is currently maintained by Daniel Robbins. To report a
737737
bug or request an enhancement, use the issue tracker at
738738
L<https://github.com/danielrobbins/keychain>.
739739

740+
Keychain includes bash completion support for command-line options, SSH keys,
741+
GPG keys, and extended mode prefixes (C<sshk:>, C<gpgk:>, C<host:>). The
742+
completion script is included in the source tarball at
743+
C<completions/keychain.bash>. For installation instructions, see the README
744+
file or run C<make install-completions>.
745+
740746
The former Funtoo Linux wiki page is preserved only as an historical reference:
741747
L<https://www.funtoo.org/Funtoo:Keychain>.

scripts/release-create.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ notes_file=$(mktemp)
1313
# Artifact path vars (provided by orchestrator if using CI artifacts)
1414
ASSET_KEYCHAIN=${KEYCHAIN_ASSET_KEYCHAIN:-keychain}
1515
ASSET_MAN=${KEYCHAIN_ASSET_MAN:-keychain.1}
16-
ASSET_TARBALL=${KEYCHAIN_ASSET_TARBALL:-keychain-$VER.tar.gz}
16+
ASSET_TARBALL=${KEYCHAIN_ASSET_TARBALL:-dist/keychain-$VER.tar.gz}
1717

1818
echo "Creating release $VER"
1919
json=$(mktemp)

scripts/release-orchestrate.sh

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ if [ "$MODE" = create ]; then
3535
fi
3636

3737
# 1. Ensure local assets exist
38-
for f in keychain-$VER.tar.gz keychain keychain.1; do
38+
for f in dist/keychain-$VER.tar.gz keychain keychain.1; do
3939
[ -f "$f" ] || { echo "Missing local asset: $f" >&2; exit 1; }
40-
done
40+
done
4141

4242
# 2. Fetch CI artifacts (MANDATORY)
4343
CI_DIR=".ci-artifacts-$VER"
@@ -89,13 +89,19 @@ compare_tar_content() {
8989
h2=$(tail -n +2 "$tmp_ci/$root/$rel" | sha256sum | awk '{print $1}')
9090
if [ "$h1" != "$h2" ]; then
9191
echo " keychain-$VER.tar.gz: content mismatch in $rel (beyond header)" >&2
92+
echo "--- LOCAL: $rel" >&2
93+
echo "+++ CI: $rel" >&2
94+
diff -u <(tail -n +2 "$tmp_local/$root/$rel") <(tail -n +2 "$tmp_ci/$root/$rel") | head -20 >&2
9295
mismatch=1
9396
fi
9497
else
9598
h1=$(sha256sum "$tmp_local/$root/$rel" | awk '{print $1}')
9699
h2=$(sha256sum "$tmp_ci/$root/$rel" | awk '{print $1}')
97100
if [ "$h1" != "$h2" ]; then
98101
echo " keychain-$VER.tar.gz: content mismatch in $rel" >&2
102+
echo "--- LOCAL: $rel" >&2
103+
echo "+++ CI: $rel" >&2
104+
diff -u "$tmp_local/$root/$rel" "$tmp_ci/$root/$rel" | head -20 >&2
99105
mismatch=1
100106
fi
101107
fi
@@ -111,48 +117,56 @@ EOF
111117
}
112118

113119
# Process artifacts with specialized logic
114-
for artifact in keychain keychain.1 keychain-$VER.tar.gz; do
115-
if [ ! -f "$CI_DIR/$artifact" ]; then
116-
printf ' %-20s CI copy missing; comparison failed (abort)\n' "$artifact"
120+
for artifact in keychain keychain.1 dist/keychain-$VER.tar.gz; do
121+
# Get basename for CI comparison
122+
basename_artifact=$(basename "$artifact")
123+
# Determine CI path (tarball is in dist/ subdirectory)
124+
if [ "$basename_artifact" = "keychain-$VER.tar.gz" ]; then
125+
ci_artifact_path="$CI_DIR/dist/$basename_artifact"
126+
else
127+
ci_artifact_path="$CI_DIR/$basename_artifact"
128+
fi
129+
if [ ! -f "$ci_artifact_path" ]; then
130+
printf ' %-20s CI copy missing; comparison failed (abort)\n' "$basename_artifact"
117131
diff_flag=1
118132
continue
119133
fi
120-
case "$artifact" in
134+
case "$basename_artifact" in
121135
keychain)
122-
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$CI_DIR/$artifact")
136+
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$ci_artifact_path")
123137
if [ "$L" = "$R" ]; then
124-
printf ' %-20s %s (match)\n' "$artifact" "$L"
138+
printf ' %-20s %s (match)\n' "$basename_artifact" "$L"
125139
else
126-
printf ' %-20s LOCAL %s != CI %s *DIFF*\n' "$artifact" "$L" "$R"
140+
printf ' %-20s LOCAL %s != CI %s *DIFF*\n' "$basename_artifact" "$L" "$R"
127141
diff_flag=1
128142
fi
129143
;;
130144
keychain.1)
131145
# Direct hash first
132-
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$CI_DIR/$artifact")
146+
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$ci_artifact_path")
133147
if [ "$L" = "$R" ]; then
134-
printf ' %-20s %s (match)\n' "$artifact" "$L"
148+
printf ' %-20s %s (match)\n' "$basename_artifact" "$L"
135149
else
136150
# Normalize and compare ignoring Pod::Man header line.
137-
if diff -u <(tail -n +2 "$artifact") <(tail -n +2 "$CI_DIR/$artifact") >/dev/null 2>&1; then
138-
printf ' %-20s (normalized match ignoring Pod::Man header)\n' "$artifact"
151+
if diff -u <(tail -n +2 "$artifact") <(tail -n +2 "$ci_artifact_path") >/dev/null 2>&1; then
152+
printf ' %-20s (normalized match ignoring Pod::Man header)\n' "$basename_artifact"
139153
else
140-
printf ' %-20s LOCAL %s != CI %s *DIFF* (content mismatch beyond header)\n' "$artifact" "$L" "$R"
154+
printf ' %-20s LOCAL %s != CI %s *DIFF* (content mismatch beyond header)\n' "$basename_artifact" "$L" "$R"
141155
diff_flag=1
142156
fi
143157
fi
144158
;;
145159
"keychain-$VER.tar.gz")
146-
if compare_tar_content "$artifact" "$CI_DIR/$artifact"; then
160+
if compare_tar_content "$artifact" "$ci_artifact_path"; then
147161
# If tar blob hash matches display it; else note normalized match.
148-
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$CI_DIR/$artifact")
162+
L=$(calc_sha256 "$artifact"); R=$(calc_sha256 "$ci_artifact_path")
149163
if [ "$L" = "$R" ]; then
150-
printf ' %-20s %s (match)\n' "$artifact" "$L"
164+
printf ' %-20s %s (match)\n' "$basename_artifact" "$L"
151165
else
152-
printf ' %-20s (content match; tar/gzip metadata differ)\n' "$artifact"
166+
printf ' %-20s (content match; tar/gzip metadata differ)\n' "$basename_artifact"
153167
fi
154168
else
155-
printf ' %-20s *CONTENT DIFF* (see above messages)\n' "$artifact"
169+
printf ' %-20s *CONTENT DIFF* (see above messages)\n' "$basename_artifact"
156170
diff_flag=1
157171
fi
158172
;;
@@ -168,8 +182,8 @@ if [ $diff_flag -ne 0 ]; then
168182
echo " VER=$VER; CI_DIR=$CI_DIR" >&2
169183
echo " diff -u keychain \"$CI_DIR/keychain\"" >&2
170184
echo " diff -u keychain.1 \"$CI_DIR/keychain.1\"" >&2
171-
echo " diff -u <(tar tzf keychain-$VER.tar.gz | sort) <(tar tzf $CI_DIR/keychain-$VER.tar.gz | sort)" >&2
172-
echo " mkdir -p /tmp/kc-local /tmp/kc-ci && tar xzf keychain-$VER.tar.gz -C /tmp/kc-local && tar xzf $CI_DIR/keychain-$VER.tar.gz -C /tmp/kc-ci && diff -ru /tmp/kc-local/keychain-$VER /tmp/kc-ci/keychain-$VER" >&2
185+
echo " diff -u <(tar tzf dist/keychain-$VER.tar.gz | sort) <(tar tzf $CI_DIR/dist/keychain-$VER.tar.gz | sort)" >&2
186+
echo " mkdir -p /tmp/kc-local /tmp/kc-ci && tar xzf dist/keychain-$VER.tar.gz -C /tmp/kc-local && tar xzf $CI_DIR/dist/keychain-$VER.tar.gz -C /tmp/kc-ci && diff -ru /tmp/kc-local/keychain-$VER /tmp/kc-ci/keychain-$VER" >&2
173187
echo
174188
if [ "${KEYCHAIN_FORCE_LOCAL:-}" = 1 ]; then
175189
echo "KEYCHAIN_FORCE_LOCAL=1 set: proceeding using LOCAL artifacts despite mismatches." >&2
@@ -182,13 +196,13 @@ fi
182196
if [ "${KEYCHAIN_FORCE_LOCAL:-}" = 1 ]; then
183197
KEYCHAIN_ASSET_KEYCHAIN="keychain"
184198
KEYCHAIN_ASSET_MAN="keychain.1"
185-
KEYCHAIN_ASSET_TARBALL="keychain-$VER.tar.gz"
199+
KEYCHAIN_ASSET_TARBALL="dist/keychain-$VER.tar.gz"
186200
echo "Source selection: USING LOCAL artifacts (override)." >&2
187201
else
188202
# All artifacts matched (raw or normalized) -> use CI versions
189203
KEYCHAIN_ASSET_KEYCHAIN="$CI_DIR/keychain"
190204
KEYCHAIN_ASSET_MAN="$CI_DIR/keychain.1"
191-
KEYCHAIN_ASSET_TARBALL="$CI_DIR/keychain-$VER.tar.gz"
205+
KEYCHAIN_ASSET_TARBALL="$CI_DIR/dist/keychain-$VER.tar.gz"
192206
echo "Source selection: USING CI artifacts (canonical)." >&2
193207
fi
194208
export KEYCHAIN_ASSET_KEYCHAIN KEYCHAIN_ASSET_MAN KEYCHAIN_ASSET_TARBALL

scripts/release-refresh.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ done
2222
echo "Uploading replacement assets..."
2323
ASSET_KEYCHAIN=${KEYCHAIN_ASSET_KEYCHAIN:-keychain}
2424
ASSET_MAN=${KEYCHAIN_ASSET_MAN:-keychain.1}
25-
ASSET_TARBALL=${KEYCHAIN_ASSET_TARBALL:-keychain-$VER.tar.gz}
25+
ASSET_TARBALL=${KEYCHAIN_ASSET_TARBALL:-dist/keychain-$VER.tar.gz}
2626

2727
# (Note: By default we do not modify existing release notes. Set KEYCHAIN_UPDATE_NOTES=1 to rebuild.)
2828

0 commit comments

Comments
 (0)