Skip to content

Commit f1f577e

Browse files
committed
ci: address second Copilot follow-up
Cross-port of dunglas/mercure#1246 follow-up: - Verify the resumed commit actually contains the expected caddy/go.mod frankenphp pin and a non-trivial PGO profile before re-tagging or dispatching downstream builds. - Use --no-renames so renames decompose into add+delete and both halves land in the API tree mutation. - Preserve each file's existing mode (executable bit) when building tree entries instead of hardcoding 100644. - Scope the concurrency group per version so a pending environment approval doesn't block dispatches for a different version.
1 parent 1166335 commit f1f577e

1 file changed

Lines changed: 42 additions & 9 deletions

File tree

.github/workflows/release.yaml

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ permissions:
1515
contents: write
1616
actions: write # to dispatch downstream binary build workflows
1717
concurrency:
18-
group: ${{ github.workflow }}
18+
# Per-version: different versions race safely (the API parent_sha
19+
# check rejects a stale main HEAD update); same-version dispatches
20+
# serialize so resume logic isn't blocked by a pending approval.
21+
group: ${{ github.workflow }}-${{ inputs.version }}
1922
cancel-in-progress: false
2023
jobs:
2124
release:
@@ -100,6 +103,20 @@ jobs:
100103
exit 1
101104
fi
102105
fi
106+
# Verify the tagged commit actually contains the expected
107+
# bump — protects against a tag created manually or by an
108+
# earlier run on stale code.
109+
git fetch --quiet origin "refs/tags/v${VERSION}:refs/tags/v${VERSION}"
110+
if ! git show "v${VERSION}:caddy/go.mod" \
111+
| grep -qE "^[[:space:]]+github\\.com/dunglas/frankenphp v${VERSION//./\\.}\$"; then
112+
echo "::error::v${VERSION} (${sha}) caddy/go.mod does not require frankenphp v${VERSION}."
113+
exit 1
114+
fi
115+
pgo_size=$(git cat-file -s "v${VERSION}:caddy/frankenphp/default.pgo" 2>/dev/null || echo 0)
116+
if [[ "${pgo_size}" -lt 1024 ]]; then
117+
echo "::error::v${VERSION} (${sha}) PGO profile is missing or suspiciously small (${pgo_size} bytes)."
118+
exit 1
119+
fi
103120
echo "Resuming: v${VERSION} exists at ${sha}"
104121
{
105122
echo "resume=true"
@@ -179,10 +196,11 @@ jobs:
179196
180197
# Capture every touched file (modifications, additions,
181198
# deletions) so transitive go.sum or PGO side effects aren't
182-
# dropped from the release commit. Deletions are represented
183-
# with a null sha in the tree.
184-
mapfile -t modified < <(git diff --name-only --diff-filter=ACMR HEAD)
185-
mapfile -t deleted < <(git diff --name-only --diff-filter=D HEAD)
199+
# dropped from the release commit. --no-renames decomposes
200+
# renames into add+delete so both halves land in the tree
201+
# mutation.
202+
mapfile -t modified < <(git diff --no-renames --name-only --diff-filter=ACM HEAD)
203+
mapfile -t deleted < <(git diff --no-renames --name-only --diff-filter=D HEAD)
186204
mapfile -t untracked < <(git ls-files --others --exclude-standard)
187205
if [[ ${#modified[@]} -eq 0 && ${#deleted[@]} -eq 0 && ${#untracked[@]} -eq 0 ]]; then
188206
echo "::error::No file changes after PGO/bump. Is v${VERSION} already on main? Delete the local tags and pick a different version, or recreate the tags manually."
@@ -192,16 +210,31 @@ jobs:
192210
[[ ${#present[@]} -gt 0 ]] && printf 'Including (added/modified): %s\n' "${present[@]}"
193211
[[ ${#deleted[@]} -gt 0 ]] && printf 'Including (deleted): %s\n' "${deleted[@]}"
194212
213+
# Preserve the existing file mode (executable bit) when
214+
# modifying tracked files; default to 100644 for new files
215+
# unless the path is executable on disk.
216+
mode_for() {
217+
local path="$1" mode
218+
mode=$(git ls-tree HEAD -- "$path" | awk '{print $1; exit}')
219+
if [[ -n "$mode" ]]; then
220+
printf '%s\n' "$mode"
221+
elif [[ -x "$path" ]]; then
222+
printf '100755\n'
223+
else
224+
printf '100644\n'
225+
fi
226+
}
227+
195228
tree_entries=$(
196229
{
197230
for path in "${modified[@]}" "${untracked[@]}"; do
198231
sha=$(make_blob "${path}")
199-
jq -nc --arg path "${path}" --arg sha "${sha}" \
200-
'{path: $path, mode: "100644", type: "blob", sha: $sha}'
232+
jq -nc --arg path "${path}" --arg sha "${sha}" --arg mode "$(mode_for "${path}")" \
233+
'{path: $path, mode: $mode, type: "blob", sha: $sha}'
201234
done
202235
for path in "${deleted[@]}"; do
203-
jq -nc --arg path "${path}" \
204-
'{path: $path, mode: "100644", type: "blob", sha: null}'
236+
jq -nc --arg path "${path}" --arg mode "$(mode_for "${path}")" \
237+
'{path: $path, mode: $mode, type: "blob", sha: null}'
205238
done
206239
} | jq -sc .
207240
)

0 commit comments

Comments
 (0)