| … | … | @@ -23,8 +23,25 @@ steps: |
| 23 | 23 | # copy the tree minus VCS, bytecode and the build dir itself |
| 24 | 24 | tar cf - --exclude=./.git --exclude=__pycache__ --exclude=./build . \ |
| 25 | 25 | | (cd build/hardops && tar xf -) |
| 26 | | (cd build && zip -qr ../hardops.zip hardops) |
| 26 | |
| 27 | # Reproducible zip. Artifacts do NOT replicate between forge backends — |
| 28 | # each daemon builds its own from the same commit — so a naive `zip -r` |
| 29 | # yields the same SIZE but a different HASH on each backend, because it |
| 30 | # stores checkout mtimes and readdir order. Behind the load balancer that |
| 31 | # makes /releases/<repo>/<version>/<file> return different bytes depending |
| 32 | # on which backend answers, and any checksum a user records is |
| 33 | # backend-specific. |
| 34 | # |
| 35 | # Pinning mtimes to the commit timestamp, sorting entries, and -X |
| 36 | # (drop extra file attributes) makes independent builds of one commit |
| 37 | # byte-identical, so the URL is a stable identifier again. |
| 38 | TS=$(git log -1 --format=%ct 2>/dev/null || echo 0) |
| 39 | cd build |
| 40 | find hardops -exec touch -h -d "@$TS" {} + |
| 41 | find hardops -print | LC_ALL=C sort | zip -X -q ../hardops.zip -@ |
| 42 | cd .. |
| 27 | 43 | ls -l hardops.zip |
| 44 | sha256sum hardops.zip |
| 28 | 45 | timeout: 300 |
| 29 | 46 | |
| 30 | 47 | artifacts: |