|
26 | 26 |
|
27 | 27 | - name: Install mcpp |
28 | 28 | run: | |
29 | | - xlings update |
30 | | - xlings install "mcpp@$MCPP_VERSION" -y -g |
| 29 | + # ⚠️ A LOOP, BECAUSE ONE `xlings update` CAN RETURN A STALE INDEX |
| 30 | + # WITHOUT SAYING SO. |
| 31 | + # |
| 32 | + # The index is published as an artifact behind a pointer, and that |
| 33 | + # pointer propagates asynchronously after a version bump is merged. |
| 34 | + # Measured on release day: an update run four minutes after the merge |
| 35 | + # printed `index updated`, and the install then failed with |
| 36 | + # |
| 37 | + # package 'mcpp@<ver>' not found in the synced index |
| 38 | + # (xim@artifact:<an older sha>, ...), synced 0 seconds ago |
| 39 | + # |
| 40 | + # Nothing had gone wrong. The update fetched the PREVIOUS artifact, |
| 41 | + # and "synced 0 seconds ago" describes when it was fetched rather than |
| 42 | + # what it contains — which is why the message reads as freshness. |
| 43 | + # |
| 44 | + # So this is not a retry around flakiness; it is the wait that a |
| 45 | + # single update does not perform. A pin naming a version that was |
| 46 | + # never published still fails, after the last attempt, and says which |
| 47 | + # of the two situations it is. |
| 48 | + for attempt in 1 2 3 4 5 6; do |
| 49 | + xlings update > /dev/null 2>&1 || true |
| 50 | + if xlings install "mcpp@$MCPP_VERSION" -y -g; then break; fi |
| 51 | + if [ "$attempt" = 6 ]; then |
| 52 | + echo "::error::mcpp@$MCPP_VERSION never appeared in the index (6 attempts over 5 minutes). If it was just released, the pointer has not propagated; if the pin names a version that was never published, it never will." |
| 53 | + exit 1 |
| 54 | + fi |
| 55 | + echo "the index has not caught up yet (attempt $attempt of 6); waiting 60s" |
| 56 | + sleep 60 |
| 57 | + done |
31 | 58 | mcpp --version |
32 | 59 | mcpp self config --mirror GLOBAL |
33 | 60 |
|
@@ -111,8 +138,35 @@ jobs: |
111 | 138 |
|
112 | 139 | - name: Install mcpp |
113 | 140 | run: | |
114 | | - xlings update |
115 | | - xlings install "mcpp@$MCPP_VERSION" -y -g |
| 141 | + # ⚠️ A LOOP, BECAUSE ONE `xlings update` CAN RETURN A STALE INDEX |
| 142 | + # WITHOUT SAYING SO. |
| 143 | + # |
| 144 | + # The index is published as an artifact behind a pointer, and that |
| 145 | + # pointer propagates asynchronously after a version bump is merged. |
| 146 | + # Measured on release day: an update run four minutes after the merge |
| 147 | + # printed `index updated`, and the install then failed with |
| 148 | + # |
| 149 | + # package 'mcpp@<ver>' not found in the synced index |
| 150 | + # (xim@artifact:<an older sha>, ...), synced 0 seconds ago |
| 151 | + # |
| 152 | + # Nothing had gone wrong. The update fetched the PREVIOUS artifact, |
| 153 | + # and "synced 0 seconds ago" describes when it was fetched rather than |
| 154 | + # what it contains — which is why the message reads as freshness. |
| 155 | + # |
| 156 | + # So this is not a retry around flakiness; it is the wait that a |
| 157 | + # single update does not perform. A pin naming a version that was |
| 158 | + # never published still fails, after the last attempt, and says which |
| 159 | + # of the two situations it is. |
| 160 | + for attempt in 1 2 3 4 5 6; do |
| 161 | + xlings update > /dev/null 2>&1 || true |
| 162 | + if xlings install "mcpp@$MCPP_VERSION" -y -g; then break; fi |
| 163 | + if [ "$attempt" = 6 ]; then |
| 164 | + echo "::error::mcpp@$MCPP_VERSION never appeared in the index (6 attempts over 5 minutes). If it was just released, the pointer has not propagated; if the pin names a version that was never published, it never will." |
| 165 | + exit 1 |
| 166 | + fi |
| 167 | + echo "the index has not caught up yet (attempt $attempt of 6); waiting 60s" |
| 168 | + sleep 60 |
| 169 | + done |
116 | 170 | mcpp --version |
117 | 171 | mcpp self config --mirror GLOBAL |
118 | 172 |
|
|
0 commit comments