Skip to content

Commit ed59f1c

Browse files
authored
Merge pull request #34 from SolverForge/issue-15-package-verify
Add automated package content verification
2 parents 1d73ae4 + 69a4486 commit ed59f1c

6 files changed

Lines changed: 96 additions & 1 deletion

File tree

.forgejo/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ jobs:
3434

3535
- name: Run tests
3636
run: cargo test
37+
38+
- name: Verify package contents
39+
run: ./scripts/verify-package.sh

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,6 @@ jobs:
4848

4949
- name: Run tests
5050
run: cargo test
51+
52+
- name: Verify package contents
53+
run: ./scripts/verify-package.sh

.github/workflows/publish-crates.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,8 @@ jobs:
4545
- name: Dry-run publish
4646
run: cargo publish --dry-run
4747

48+
- name: Verify package contents
49+
run: ./scripts/verify-package.sh
50+
4851
- name: Publish solverforge-ui
4952
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ JS_SRC := $(sort $(wildcard js-src/*.js))
2626

2727
# ============== Phony Targets ==============
2828
.PHONY: banner help assets build build-release test test-quick test-doc test-unit test-one \
29-
lint fmt fmt-check clippy ci-local pre-release version \
29+
lint fmt fmt-check clippy ci-local pre-release version package-verify \
3030
bump-patch bump-minor bump-major bump-dry \
3131
publish-dry publish clean watch
3232

@@ -195,9 +195,16 @@ pre-release: banner
195195
@cargo test --quiet && printf "$(GREEN)$(CHECK) All tests passed$(RESET)\n"
196196
@printf "$(PROGRESS) Dry-run publish...\n"
197197
@cargo publish --dry-run 2>&1 | tail -1
198+
@printf "$(PROGRESS) Verifying packaged contents...\n"
199+
@./scripts/verify-package.sh
198200
@printf "$(GREEN)$(CHECK) Package valid$(RESET)\n"
199201
@printf "\n$(GREEN)$(BOLD)$(CHECK) Ready for release v$(VERSION)$(RESET)\n\n"
200202

203+
package-verify:
204+
@printf "$(PROGRESS) Verifying packaged crate contents...\n"
205+
@./scripts/verify-package.sh
206+
@printf "$(GREEN)$(CHECK) Package contents verified$(RESET)\n"
207+
201208
# ============== Publishing ==============
202209

203210
publish-dry: test banner
@@ -206,6 +213,7 @@ publish-dry: test banner
206213
@printf "$(CYAN)$(BOLD)╚══════════════════════════════════════════════════════════╝$(RESET)\n\n"
207214
@printf "$(GREEN)$(CHECK) All tests passed$(RESET)\n"
208215
@cargo publish --dry-run && \
216+
./scripts/verify-package.sh && \
209217
printf "$(GREEN)$(CHECK) Package valid$(RESET)\n" || \
210218
(printf "$(RED)$(CROSS) Package validation failed$(RESET)\n" && exit 1)
211219
@printf "\n$(GRAY)Use 'make publish' to publish v$(VERSION) to crates.io$(RESET)\n\n"

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,12 @@ Consumer integration stays npm-free. Maintainer release automation does not.
500500

501501
If you are cutting a release locally, make sure Node.js with `npx` is available before using the `bump-*` targets. After the bump completes, push the release commit and tag with `git push --follow-tags` or an equivalent tag-push command so the release automation actually starts.
502502

503+
## Package Verification
504+
505+
Use `make package-verify` to inspect the exact crate contents that would be published.
506+
507+
The verification step checks that required bundled assets and crate metadata are present, and that development-only sources such as `css-src/`, `js-src/`, `scripts/`, and screenshots are not shipped in the published crate.
508+
503509
## Acknowledgments
504510

505511
solverforge-ui builds on these excellent open-source projects:

scripts/verify-package.sh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
manifest="$(mktemp)"
5+
trap 'rm -f "$manifest"' EXIT
6+
7+
cargo package --allow-dirty --list > "$manifest"
8+
9+
if command -v rg >/dev/null 2>&1; then
10+
search_exact() {
11+
rg -Fxq "$1" "$manifest"
12+
}
13+
14+
search_prefix() {
15+
rg -q "^$1" "$manifest"
16+
}
17+
else
18+
search_exact() {
19+
grep -Fxq "$1" "$manifest"
20+
}
21+
22+
search_prefix() {
23+
grep -Eq "^$1" "$manifest"
24+
}
25+
fi
26+
27+
require() {
28+
local path="$1"
29+
if ! search_exact "$path"; then
30+
echo "missing packaged file: $path" >&2
31+
exit 1
32+
fi
33+
}
34+
35+
reject_prefix() {
36+
local prefix="$1"
37+
if search_prefix "$prefix"; then
38+
echo "unexpected packaged path matching prefix: $prefix" >&2
39+
exit 1
40+
fi
41+
}
42+
43+
reject_exact() {
44+
local path="$1"
45+
if search_exact "$path"; then
46+
echo "unexpected packaged file: $path" >&2
47+
exit 1
48+
fi
49+
}
50+
51+
require "Cargo.toml"
52+
require "Cargo.lock"
53+
require "README.md"
54+
require "LICENSE"
55+
require "CHANGELOG.md"
56+
require "src/lib.rs"
57+
require "static/sf/sf.css"
58+
require "static/sf/sf.js"
59+
require "static/sf/vendor/frappe-gantt/frappe-gantt.min.js"
60+
require "static/sf/vendor/split/split.min.js"
61+
require "static/sf/fonts/space-grotesk.woff2"
62+
require "static/sf/fonts/jetbrains-mono.woff2"
63+
require "static/sf/img/solverforge-logo.svg"
64+
65+
reject_prefix "css-src/"
66+
reject_prefix "js-src/"
67+
reject_prefix "screenshots/"
68+
reject_prefix "scripts/"
69+
reject_exact "WIREFRAME.md"
70+
reject_exact ".versionrc.json"
71+
72+
echo "package contents verified"

0 commit comments

Comments
 (0)