Development¶
make test # unit tests, no network
make build # -> bin/pier
make test-integration # e2e: needs PIER_TEST_S3_ENDPOINT (S3Mock/rclone serve s3)
Integration test:
# start an S3-compatible store (rclone serve s3 works too):
# docker run --rm -p 9090:9090 adobe/s3mock
PIER_TEST_S3_ENDPOINT=http://127.0.0.1:9090 \
PIER_TEST_S3_USER=testuser PIER_TEST_S3_PASS=testpass \
PIER_TEST_S3_BUCKET=pier-integration \
go test -tags integration ./test/integration
Design decisions¶
- Plugin-maintained metadata is last-writer-wins. The deploy
plugin's read-modify-write spans separate
GETandPUTrequests, which Pier cannot serialize, so concurrent deploys of different versions of the same GAV resolve last-writer-wins on the plugin-maintained document. Pier does not merge concurrent plugin writes. It does serialize its own read-modify-write — artifactPUT - metadata invalidation, metadata synthesis, and plugin metadata
PUTs — per GAV under an in-process lock, relying on S3's consistent read-after-write. Pier does not track metadata written directly to S3 (bypassing Pier) — only Pier-mediatedPUTs trigger the synthesis invalidation. - In-process per-GAV serialization, no cross-instance coordination.
The per-GAV locks are process-local: simple, at a cost. With multiple
replicas, Pier does not serialize concurrent operations on the same
GAV across instances. The next artifact
PUTfor the GAV heals a bounded stale-document window. - Single repository root. One flat repository per instance; the
namespace is the group id, with
reserved_groupssplitting internal uploads from the pull-through cache. No named repositories. DELETEremoves one object. No delete by prefix: bulk removal (a version, a group, a stale cached prefix) is an operator action on S3 — lifecycle rules,aws s3 rm, rclone — not a repository operation.