Skip to content

Commit c8d6047

Browse files
committed
version theme releases per file and drop sync fallbacks
1 parent 59b67d8 commit c8d6047

2 files changed

Lines changed: 116 additions & 71 deletions

File tree

.github/workflows/sync-theme-releases.yml

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,60 @@ jobs:
3131
echo "mode=all" >> "$GITHUB_OUTPUT"
3232
exit 0
3333
fi
34+
3435
before="${{ github.event.before }}"
35-
if [[ -z "$before" || "$before" =~ ^0+$ ]]; then
36-
echo "mode=all" >> "$GITHUB_OUTPUT"
37-
exit 0
36+
if [[ -z "$before" ]]; then
37+
echo "github.event.before is empty; cannot compute XML delta" >&2
38+
exit 1
3839
fi
39-
if ! git cat-file -e "${before}^{commit}" 2>/dev/null; then
40-
echo "mode=all" >> "$GITHUB_OUTPUT"
41-
exit 0
40+
if [[ "$before" =~ ^0+$ ]]; then
41+
echo "github.event.before is a zero SHA; push delta is unavailable" >&2
42+
exit 1
4243
fi
43-
mapfile -t added_modified < <(git diff --name-only --diff-filter=AM "$before" "${{ github.sha }}" -- '*.xml' | grep -v '^\.github/' | grep -v '^tmp/' || true)
44-
mapfile -t deleted < <(git diff --name-only --diff-filter=D "$before" "${{ github.sha }}" -- '*.xml' | grep -v '^\.github/' | grep -v '^tmp/' || true)
44+
if ! git cat-file -e "${before}^{commit}"; then
45+
echo "commit $before is not in this clone; cannot compute XML delta" >&2
46+
exit 1
47+
fi
48+
49+
sync_file="$(mktemp)"
50+
delete_file="$(mktemp)"
51+
trap 'rm -f "$sync_file" "$delete_file"' EXIT
52+
53+
while IFS=$'\t' read -r status path extra; do
54+
[[ -z "${status:-}" || -z "${path:-}" ]] && continue
55+
case "$status" in
56+
A|M)
57+
[[ "$path" == .github/* || "$path" == tmp/* ]] && continue
58+
printf '%s\n' "$path" >> "$sync_file"
59+
;;
60+
D)
61+
[[ "$path" == .github/* || "$path" == tmp/* ]] && continue
62+
printf '%s\n' "$path" >> "$delete_file"
63+
;;
64+
R*)
65+
[[ "$path" == .github/* || "$path" == tmp/* ]] && continue
66+
printf '%s\n' "$path" >> "$delete_file"
67+
[[ -z "${extra:-}" ]] && {
68+
echo "rename is missing destination path: $status $path" >&2
69+
exit 1
70+
}
71+
[[ "$extra" == .github/* || "$extra" == tmp/* ]] && continue
72+
printf '%s\n' "$extra" >> "$sync_file"
73+
;;
74+
*)
75+
echo "unhandled git name-status: $status $path ${extra-}" >&2
76+
exit 1
77+
;;
78+
esac
79+
done < <(git diff --name-status --diff-filter=AMRD -M "$before" "${{ github.sha }}" -- '*.xml')
80+
4581
{
4682
echo "mode=delta"
4783
echo "sync<<EOF"
48-
printf '%s\n' "${added_modified[@]-}"
84+
sort -u "$sync_file"
4985
echo "EOF"
5086
echo "delete<<EOF"
51-
printf '%s\n' "${deleted[@]-}"
87+
sort -u "$delete_file"
5288
echo "EOF"
5389
} >> "$GITHUB_OUTPUT"
5490
@@ -71,11 +107,8 @@ jobs:
71107
[[ -z "$path" ]] && continue
72108
args+=(--delete "$path")
73109
done <<< "${{ steps.changes.outputs.delete }}"
74-
if [[ ${#args[@]} -eq 0 ]]; then
75-
args+=(--all)
76-
fi
77110
fi
78-
./scripts/sync-theme-releases.sh "${args[@]}"
111+
./scripts/sync-theme-releases.sh ${args[@]+"${args[@]}"}
79112
80113
- name: Commit README download links
81114
run: |

scripts/sync-theme-releases.sh

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,22 @@ title_case() {
2121
theme_meta() {
2222
local path="$1" base vendor theme_name version_label theme_slug tag asset
2323
path="${path#./}"
24+
[[ "$path" == *.xml ]] || { echo "not an xml path: $path" >&2; return 1; }
2425
base="${path##*/}"
2526
base="${base%.xml}"
2627
vendor="$(slugify "${path%%/*}")"
27-
if [[ "$base" =~ ^(.+)[[:space:]]+([0-9]+([.][0-9]+)*)$ ]]; then
28-
theme_name="${BASH_REMATCH[1]}"
29-
version_label="${BASH_REMATCH[2]}"
30-
else
31-
theme_name="$base"
32-
version_label=""
28+
[[ -n "$vendor" && "$vendor" != "$(slugify "$base")" ]] || {
29+
echo "theme xml must live under a vendor folder: $path" >&2
30+
return 1
31+
}
32+
if [[ ! "$base" =~ ^(.+)[[:space:]]+([0-9]+([.][0-9]+)*)$ ]]; then
33+
echo "invalid theme filename (expected 'Name 1.0.xml'): $path" >&2
34+
return 1
3335
fi
36+
theme_name="${BASH_REMATCH[1]}"
37+
version_label="${BASH_REMATCH[2]}"
3438
theme_slug="$(slugify "$theme_name")"
35-
tag="${vendor}-${theme_slug}"
39+
tag="${vendor}-${theme_slug}-${version_label}"
3640
asset="${base// /-}.xml"
3741
printf '%s\t%s\t%s\t%s\t%s\t%s\n' "$path" "$tag" "$asset" "$theme_name" "$version_label" "$vendor"
3842
}
@@ -69,23 +73,45 @@ release_exists() {
6973
gh release view "$1" --repo "$REPO" >/dev/null 2>&1
7074
}
7175

76+
file_sha256() {
77+
shasum -a 256 "$1" | awk '{print $1}'
78+
}
79+
7280
upload_asset() {
73-
local tag="$1" src="$2" asset="$3" title="$4" notes="$5" staged old
81+
local tag="$1" src="$2" asset="$3" title="$4" notes="$5"
82+
local staged old local_sha remote_dir remote_sha
7483
staged="$WORKDIR/$asset"
7584
cp "$src" "$staged"
76-
if release_exists "$tag"; then
77-
while IFS= read -r old; do
78-
[[ -z "$old" || "$old" == "$asset" ]] && continue
79-
gh release delete-asset "$tag" "$old" --repo "$REPO" --yes
80-
done < <(gh release view "$tag" --repo "$REPO" --json assets -q '.assets[].name')
81-
gh release upload "$tag" "$staged" --repo "$REPO" --clobber
82-
gh release edit "$tag" --repo "$REPO" --title "$title" --notes "$notes"
83-
else
85+
local_sha="$(file_sha256 "$staged")"
86+
87+
if ! release_exists "$tag"; then
8488
gh release create "$tag" "$staged" --repo "$REPO" \
8589
--title "$title" \
8690
--notes "$notes" \
8791
--latest=false
92+
return 0
8893
fi
94+
95+
while IFS= read -r old; do
96+
[[ -z "$old" || "$old" == "$asset" ]] && continue
97+
gh release delete-asset "$tag" "$old" --repo "$REPO" --yes
98+
printf 'removed stale asset %s from %s\n' "$old" "$tag"
99+
done < <(gh release view "$tag" --repo "$REPO" --json assets -q '.assets[].name')
100+
101+
if gh release view "$tag" --repo "$REPO" --json assets -q '.assets[].name' | grep -Fxq "$asset"; then
102+
remote_dir="$WORKDIR/remote-$tag"
103+
mkdir -p "$remote_dir"
104+
gh release download "$tag" --repo "$REPO" --pattern "$asset" --dir "$remote_dir" --clobber
105+
remote_sha="$(file_sha256 "$remote_dir/$asset")"
106+
if [[ "$local_sha" == "$remote_sha" ]]; then
107+
gh release edit "$tag" --repo "$REPO" --title "$title" --notes "$notes"
108+
printf 'unchanged %s/%s\n' "$tag" "$asset"
109+
return 0
110+
fi
111+
fi
112+
113+
gh release upload "$tag" "$staged" --repo "$REPO" --clobber
114+
gh release edit "$tag" --repo "$REPO" --title "$title" --notes "$notes"
89115
}
90116

91117
delete_theme_release() {
@@ -96,15 +122,18 @@ delete_theme_release() {
96122

97123
sync_one() {
98124
local path="$1" meta tag asset theme_name version_label vendor title notes
99-
[[ -f "$path" ]] || return 0
100-
meta="$(theme_meta "$path")"
125+
[[ -f "$path" ]] || { echo "missing theme file: $path" >&2; return 1; }
126+
meta="$(theme_meta "$path")" || return 1
101127
IFS=$'\t' read -r path tag asset theme_name version_label vendor <<<"$meta"
102-
title="${theme_name} (${vendor})"
128+
title="${theme_name} ${version_label}"
103129
notes="Cleaned free Blogger theme XML.
104130
105131
Source: \`${path}\`
132+
Theme: ${theme_name}
133+
Version: ${version_label}
134+
Vendor: ${vendor}
106135
107-
One stable release per theme. Pushes that change this file replace the download asset in place."
136+
Each \`Name Version.xml\` file has its own release tag. Updating this file replaces the asset on this release only."
108137
upload_asset "$tag" "$path" "$asset" "$title" "$notes"
109138
printf 'synced %s -> %s/%s\n' "$path" "$tag" "$asset"
110139
}
@@ -124,47 +153,28 @@ render_readme_section() {
124153
printf '| **%s** | %s | [Download XML](%s) |\n' "$theme_name" "$version_label" "$url"
125154
done < <(
126155
while IFS= read -r path; do
127-
theme_meta "$path"
156+
theme_meta "$path" || exit 1
128157
done < <(list_theme_xmls)
129158
)
130159
}
131160

132161
update_readme() {
133162
local readme="$ROOT/README.md" section_file="$WORKDIR/section.md" out="$WORKDIR/README.out"
134-
[[ -f "$readme" ]] || return 0
163+
[[ -f "$readme" ]] || { echo "missing README.md" >&2; exit 1; }
164+
grep -Fq "$MARKER_START" "$readme" || { echo "README.md missing $MARKER_START" >&2; exit 1; }
165+
grep -Fq "$MARKER_END" "$readme" || { echo "README.md missing $MARKER_END" >&2; exit 1; }
135166
render_readme_section >"$section_file"
136-
137-
if grep -Fq "$MARKER_START" "$readme" && grep -Fq "$MARKER_END" "$readme"; then
138-
awk -v start="$MARKER_START" -v end="$MARKER_END" -v sf="$section_file" '
139-
$0 == start {
140-
print
141-
while ((getline line < sf) > 0) print line
142-
close(sf)
143-
skip=1
144-
next
145-
}
146-
$0 == end { skip=0; print; next }
147-
!skip { print }
148-
' "$readme" >"$out"
149-
else
150-
awk -v sf="$section_file" '
151-
/^## Download$/ {
152-
print
153-
print ""
154-
print "Themes are grouped by vendor. New vendor sections will be added as more cleaned XMLs are published."
155-
print ""
156-
print "<!-- download:start -->"
157-
while ((getline line < sf) > 0) print line
158-
close(sf)
159-
print "<!-- download:end -->"
160-
print ""
161-
skip=1
162-
next
163-
}
164-
skip && /^## / { skip=0 }
165-
!skip { print }
166-
' "$readme" >"$out"
167-
fi
167+
awk -v start="$MARKER_START" -v end="$MARKER_END" -v sf="$section_file" '
168+
$0 == start {
169+
print
170+
while ((getline line < sf) > 0) print line
171+
close(sf)
172+
skip=1
173+
next
174+
}
175+
$0 == end { skip=0; print; next }
176+
!skip { print }
177+
' "$readme" >"$out"
168178
mv "$out" "$readme"
169179
}
170180

@@ -206,7 +216,8 @@ fi
206216

207217
for path in "${SYNC_PATHS[@]+"${SYNC_PATHS[@]}"}"; do
208218
[[ -z "${path:-}" ]] && continue
209-
IFS=$'\t' read -r _ tag _ _ _ _ <<<"$(theme_meta "$path")"
219+
meta="$(theme_meta "$path")" || exit 1
220+
IFS=$'\t' read -r _ tag _ _ _ _ <<<"$meta"
210221
printf '%s\n' "$tag" >>"$EXPECTED_TAGS"
211222
done
212223

@@ -222,14 +233,15 @@ fi
222233

223234
for path in "${DELETE_PATHS[@]+"${DELETE_PATHS[@]}"}"; do
224235
[[ -z "${path:-}" ]] && continue
225-
IFS=$'\t' read -r _ tag _ _ _ _ <<<"$(theme_meta "$path")"
236+
meta="$(theme_meta "$path")" || exit 1
237+
IFS=$'\t' read -r _ tag _ _ _ _ <<<"$meta"
226238
delete_theme_release "$tag"
227239
printf 'deleted release for %s (%s)\n' "$path" "$tag"
228240
done
229241

230242
for path in "${SYNC_PATHS[@]+"${SYNC_PATHS[@]}"}"; do
231243
[[ -z "${path:-}" ]] && continue
232-
sync_one "$path"
244+
sync_one "$path" || exit 1
233245
done
234246

235247
update_readme

0 commit comments

Comments
 (0)