Skip to content

Zip Folders On Release #180

Zip Folders On Release

Zip Folders On Release #180

name: Zip Folders On Release
on:
push:
tags:
- "v*"
release:
types: [published]
permissions:
contents: write
jobs:
zip-and-upload:
if: github.event_name != 'release' || github.event.sender.login != 'github-actions[bot]'
runs-on: ubuntu-latest
concurrency:
group: release-${{ github.event_name == 'release' && github.event.release.tag_name || github.ref_name }}
cancel-in-progress: false
env:
TAG_NAME: ${{ github.event_name == 'release' && github.event.release.tag_name || github.ref_name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ env.TAG_NAME }}
- name: Prepare release metadata
shell: bash
run: |
set -euo pipefail
VERSION="${TAG_NAME#v}"
export VERSION
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "Release tag: ${TAG_NAME}"
echo "Normalized version: ${VERSION}"
- name: Update script.json versions
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
import json
import os
version = os.environ["VERSION"]
updated = 0
for root, _, files in os.walk("."):
if "script.json" not in files:
continue
path = os.path.join(root, "script.json")
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
data["version"] = version
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
f.write("\n")
updated += 1
print(f"Updated {path}")
print(f"Updated {updated} script.json file(s).")
PY
- name: Create zip archives for each top-level folder
shell: bash
run: |
set -euo pipefail
mkdir -p dist
for dir in */; do
folder="${dir%/}"
# Skip metadata, build output, and source folders.
if [[ "$folder" == ".github" || "$folder" == "dist" || "$folder" == "src" ]]; then
continue
fi
echo "Zipping $folder -> dist/${folder}.zip"
zip -r "dist/${folder}.zip" "$folder"
done
echo "Generated archives:"
ls -lh dist
- name: Generate release notes
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
mapfile -t TAGS < <(git tag --list 'v*' --sort=-version:refname)
PREVIOUS_TAG=""
for i in "${!TAGS[@]}"; do
if [[ "${TAGS[$i]}" == "$TAG_NAME" ]]; then
NEXT_INDEX=$((i + 1))
if [[ "$NEXT_INDEX" -lt "${#TAGS[@]}" ]]; then
PREVIOUS_TAG="${TAGS[$NEXT_INDEX]}"
fi
break
fi
done
NOTES_FILE="release-notes.md"
{
echo "## 更新内容"
echo
if [[ -n "$PREVIOUS_TAG" ]]; then
echo "基于 \`$PREVIOUS_TAG\` 到 \`$TAG_NAME\` 的提交:"
echo
else
echo "首个版本,包含以下提交:"
echo
fi
} > "$NOTES_FILE"
if [[ -n "$PREVIOUS_TAG" ]]; then
gh api "repos/${GITHUB_REPOSITORY}/compare/${PREVIOUS_TAG}...${TAG_NAME}" > compare.json
python3 - <<'PY'
import json
import os
repo = os.environ["GITHUB_REPOSITORY"]
notes_file = "release-notes.md"
with open("compare.json", "r", encoding="utf-8") as f:
data = json.load(f)
commits = data.get("commits", [])
with open(notes_file, "a", encoding="utf-8") as f:
if commits:
for commit in commits:
sha = commit["sha"]
short_sha = sha[:7]
message = commit["commit"]["message"].splitlines()[0]
f.write(f"- {message} ([{short_sha}](https://github.com/{repo}/commit/{sha}))\n")
else:
f.write("- No commits found.\n")
PY
else
COMMITS="$(git log --reverse --pretty=format:"- %s ([%h](https://github.com/${GITHUB_REPOSITORY}/commit/%H))" "$TAG_NAME" || true)"
if [[ -n "$COMMITS" ]]; then
printf '%s\n' "$COMMITS" >> "$NOTES_FILE"
else
echo "- No commits found." >> "$NOTES_FILE"
fi
fi
if [[ -n "$PREVIOUS_TAG" ]]; then
{
echo
echo "**完整对比**: https://github.com/${GITHUB_REPOSITORY}/compare/${PREVIOUS_TAG}...${TAG_NAME}"
} >> "$NOTES_FILE"
fi
echo "Release notes preview:"
cat "$NOTES_FILE"
- name: Create or update GitHub release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
gh release edit "$TAG_NAME" --title "$TAG_NAME" --notes-file release-notes.md
gh release upload "$TAG_NAME" dist/*.zip --clobber
else
gh release create "$TAG_NAME" dist/*.zip --title "$TAG_NAME" --notes-file release-notes.md
fi