Assert the release zip's shape before publishing
Uploads are immutable, so a malformed archive cannot be replaced at its version path. verify-package checks the zip has one top-level directory, carries lua/, plugin/, doc/ and README.md, and leaks no dev or CI files.
This commit is contained in:
@@ -23,8 +23,9 @@ steps:
|
||||
- name: package
|
||||
image: alpine:3.22
|
||||
commands:
|
||||
- apk add --no-cache git make
|
||||
- apk add --no-cache git make unzip
|
||||
- make package VERSION=${CI_COMMIT_TAG}
|
||||
- make verify-package VERSION=${CI_COMMIT_TAG}
|
||||
depends_on: [test]
|
||||
backend_options:
|
||||
kubernetes:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: test lint fmt pre-commit package patch minor major _tag
|
||||
.PHONY: test lint fmt pre-commit package verify-package patch minor major _tag
|
||||
|
||||
VERSION ?= $(shell git describe --tags --always)
|
||||
# Archive names drop the leading "v", the way tag source archives do.
|
||||
@@ -24,6 +24,35 @@ package:
|
||||
git archive --format=zip --prefix=arti-pack-$(BARE_VERSION)/ -o $(ARCHIVE) HEAD
|
||||
@echo $(ARCHIVE)
|
||||
|
||||
# Published uploads are immutable, so a malformed archive cannot be replaced at
|
||||
# its version path. Assert the shape before anything ships.
|
||||
RUNTIME_PATHS = lua/ plugin/ doc/ README.md
|
||||
EXCLUDED_PATHS = tests/ .woodpecker/ Makefile .editorconfig .gitattributes \
|
||||
.gitignore .luacheckrc .pre-commit-config.yaml .stylua.toml
|
||||
|
||||
verify-package:
|
||||
@test -f $(ARCHIVE) || { echo "verify-package: $(ARCHIVE) not built"; exit 1; }
|
||||
@names=$$(unzip -Z1 $(ARCHIVE)); \
|
||||
roots=$$(printf '%s\n' "$$names" | cut -d/ -f1 | sort -u); \
|
||||
if [ "$$(printf '%s\n' "$$roots" | wc -l)" -ne 1 ]; then \
|
||||
echo "verify-package: expected one top-level directory, found:"; \
|
||||
printf ' %s\n' $$roots; exit 1; \
|
||||
fi; \
|
||||
fail=0; \
|
||||
printf '%s\n' "$$names" | grep -q "^$$roots/." || \
|
||||
{ echo "verify-package: top-level $$roots is not a directory"; fail=1; }; \
|
||||
for p in $(RUNTIME_PATHS); do \
|
||||
printf '%s\n' "$$names" | grep -q "^$$roots/$$p" || \
|
||||
{ echo "verify-package: missing runtime path $$p"; fail=1; }; \
|
||||
done; \
|
||||
for p in $(EXCLUDED_PATHS); do \
|
||||
if printf '%s\n' "$$names" | grep -q "^$$roots/$$p"; then \
|
||||
echo "verify-package: excluded path $$p leaked into the archive"; fail=1; \
|
||||
fi; \
|
||||
done; \
|
||||
[ $$fail -eq 0 ] || exit 1; \
|
||||
echo "verify-package: $(ARCHIVE) ok, root $$roots"
|
||||
|
||||
# Bump helpers — read the latest semver tag and create the next one.
|
||||
# If no tag exists yet, start from v0.0.0.
|
||||
_LATEST = $(shell git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$$' | head -1)
|
||||
|
||||
Reference in New Issue
Block a user