@@ -1511,12 +1511,18 @@ pub(crate) mod tests {
15111511 super :: documented_commands ( "docs/getting-started.md" )
15121512 }
15131513
1514- /// Publishing moves the mutable tag, and three of the four jobs that
1515- /// validate a published image read that tag. So dispatching them
1516- /// before a publish re-tests the previous release, and the mechanism
1517- /// keeping the order right was somebody remembering it: for v0.11.0
1518- /// the validation was simply never run, and its cross-version job
1519- /// still holds an unanswered question about that release.
1514+ /// Publishing gates the mutable tag on the validation. The laps
1515+ /// install and boot the digest-pinned staging ref this run pushed;
1516+ /// the promote job moves the tags people pull only if every lap came
1517+ /// back green. Two of the first three publishes failed their
1518+ /// validations after the tags were already live (44.3.0's
1519+ /// signatures, 44.6.0's greeter) — under the old order the laps
1520+ /// could tell somebody the same day, but what they said was that
1521+ /// the broken thing was public. Composes of one commit are not
1522+ /// byte-stable (src/lock.rs: layered packages resolve live on
1523+ /// purpose), so gating on "the same image built again" is not an
1524+ /// option: the bytes that go live must be the bytes that were
1525+ /// validated.
15201526 #[ test]
15211527 fn publishing_triggers_the_workflow_that_validates_what_was_published ( ) {
15221528 let read = |name : & str | {
@@ -1533,11 +1539,22 @@ pub(crate) mod tests {
15331539 ) ;
15341540 assert ! (
15351541 publish. contains( "needs: publish" ) ,
1536- "the validation runs after the publish , so nothing it finds can unpublish anything "
1542+ "the validation runs after the staging push , so the laps see this run's bytes "
15371543 ) ;
15381544 assert ! (
1539- publish. contains( "image: ${{ needs.publish.outputs.remote }}" ) ,
1540- "the validation should test the image this run published, not a default"
1545+ publish
1546+ . contains( "image: ${{ needs.publish.outputs.staging }}@${{ needs.publish.outputs.digest }}" ) ,
1547+ "the validation should install the digest-pinned staging ref, not a default and not an unpinned tag: \
1548+ a tag can move under a concurrent publish and put different bytes under this run's verdict"
1549+ ) ;
1550+ assert ! (
1551+ publish. contains( "needs: [publish, validate]" ) ,
1552+ "the promote job waits on the validation: the tags move only when every lap is green"
1553+ ) ;
1554+ assert ! (
1555+ publish. contains( "crane tag" ) ,
1556+ "the promotion re-points the tags at the validated digest without moving bytes, \
1557+ so the digest the signature names is the digest the tags serve"
15411558 ) ;
15421559 assert ! (
15431560 read( "published.yml" ) . contains( "workflow_call:" ) ,
0 commit comments