主要功能
- 当主题或插件修改提交commit 并 push到Github时,自动打包主题插件发布一个Realease
- 判断当前版本号,如果与之前版本号相同则不发布
- .releaseignore文件设置忽略的文件或文件夹,不打包进release
主题
必须按照WordPress主题开发规范,在style.css顶部注释版本号(Version:)
文件位置:
.github/workflows/release-on-version-change.yml
内容:
name: Release on version change
on:
push:
branches:
- main
- master
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get previous commit hash
id: prev
run: |
echo "prev_commit=$(git rev-parse HEAD^)" >> $GITHUB_ENV
- name: Extract current version from style.css
id: current_version
run: |
version=$(grep -E '^(Version:|版本:)' style.css | sed 's/.*[::] *//')
if [ -z "$version" ]; then
echo "❌ 未能在当前 style.css 中找到版本号"
exit 1
fi
echo "current_version=$version" >> $GITHUB_ENV
echo "当前版本: $version"
- name: Extract previous version from last commit
id: prev_version
run: |
git show ${{ env.prev_commit }}:style.css > old_style.css || true
version=$(grep -E '^(Version:|版本:)' old_style.css | sed 's/.*[::] *//')
echo "prev_version=$version" >> $GITHUB_ENV
echo "上一个版本: $version"
- name: Compare versions
id: compare
run: |
if [ "${{ env.current_version }}" != "${{ env.prev_version }}" ]; then
echo "version_changed=true" >> $GITHUB_ENV
echo "🔄 版本变化: ${{ env.prev_version }} → ${{ env.current_version }}"
else
echo "version_changed=false" >> $GITHUB_ENV
echo "ℹ️ 版本未变化,无需发布"
fi
- name: Stop if version not changed
if: env.version_changed == 'false'
run: exit 0
- name: Check if tag already exists
id: tag_check
run: |
if git rev-parse "v${{ env.current_version }}" >/dev/null 2>&1; then
echo "tag_exists=true" >> $GITHUB_ENV
echo "⚠️ Tag v${{ env.current_version }} 已存在,跳过发布"
else
echo "tag_exists=false" >> $GITHUB_ENV
fi
- name: Stop if tag already exists
if: env.tag_exists == 'true'
run: exit 0
- name: Create Git tag
if: env.tag_exists == 'false'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git tag -a "v${{ env.current_version }}" -m "Release v${{ env.current_version }}"
git push origin "v${{ env.current_version }}"
- name: Create ZIP package (with ignore list)
run: |
ZIP_FILE="${{ github.event.repository.name }}-${{ env.current_version }}.zip"
EXCLUDE_ARGS="-x '*.git*' '.github/*'"
if [ -f ".releaseignore" ]; then
echo "🧾 使用 .releaseignore 过滤以下内容:"
while IFS= read -r line; do
if [ -n "$line" ] && [[ ! "$line" =~ ^# ]]; then
echo " - $line"
EXCLUDE_ARGS="$EXCLUDE_ARGS '$line'"
fi
done < .releaseignore
else
echo "⚠️ 未找到 .releaseignore,使用默认排除规则。"
fi
eval zip -r "$ZIP_FILE" . $EXCLUDE_ARGS
echo "✅ 打包完成:$ZIP_FILE"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ env.current_version }}
name: "Release v${{ env.current_version }}"
body: |
🎉 自动发布版本 v${{ env.current_version }}
🔖 来自 commit: ${{ github.sha }}
files: ${{ github.event.repository.name }}-${{ env.current_version }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
文件位置:
.releaseignore
内容:
# 忽略开发工具配置
.vscode/
.idea/
.gitattributes
.gitignore
.releaseignore
# 忽略文档和演示
README.md
screenshot.png
docs/
examples/
# 忽略 CI/CD 相关文件
.github/
.gitlab-ci.yml
# 忽略测试文件
tests/
*.log
# 忽略 Mac/Windows 系统文件
.DS_Store
Thumbs.db
# 忽略源代码文件
assets\main.scss
webpack.config.js
插件
必须按照WordPress插件开发规范,根目录存在插件名称php,并在顶部注释版本号(Version:)
文件位置:
.github/workflows/release-on-version-change.yml
内容:
name: Release on Plugin Version Change
on:
push:
branches:
- main
- master
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get plugin main file
id: find_plugin_file
run: |
# 查找插件主文件(假设插件主文件在仓库根目录下且带有 Plugin Name)
PLUGIN_FILE=$(grep -rl "Plugin Name:" . | head -n 1)
if [ -z "$PLUGIN_FILE" ]; then
echo "❌ 未找到插件主文件(包含 Plugin Name: 的PHP文件)。"
exit 1
fi
echo "plugin_file=$PLUGIN_FILE" >> $GITHUB_OUTPUT
echo "✅ 找到插件文件: $PLUGIN_FILE"
- name: Get current version from plugin header
id: get_version
run: |
FILE="${{ steps.find_plugin_file.outputs.plugin_file }}"
# 使用兼容 WordPress 格式的正则提取 Version 字段
VERSION=$(grep -Eim1 "^[[:space:]]*(\*|#|//)?[[:space:]]*Version:[[:space:]]*[0-9]+\.[0-9]+(\.[0-9]+)?" "$FILE" | sed -E 's/.*Version:[[:space:]]*([0-9.]+).*/\1/')
if [ -z "$VERSION" ]; then
echo "❌ 未能从插件文件中提取版本号。"
echo "文件内容示例:"
head -n 20 "$FILE"
exit 1
fi
echo "current_version=$VERSION" >> $GITHUB_OUTPUT
echo "✅ 当前版本号:$VERSION"
- name: Check if version already released
id: check_release
run: |
VERSION=${{ steps.get_version.outputs.current_version }}
EXISTING=$(gh release list --limit 100 | grep -F "v$VERSION" || true)
if [ -n "$EXISTING" ]; then
echo "⚠️ 版本 v$VERSION 已存在,跳过发布。"
echo "skip_release=true" >> $GITHUB_OUTPUT
else
echo "skip_release=false" >> $GITHUB_OUTPUT
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create ZIP package (with .releaseignore)
if: steps.check_release.outputs.skip_release == 'false'
run: |
VERSION=${{ steps.get_version.outputs.current_version }}
ZIP_FILE="${{ github.event.repository.name }}-${VERSION}.zip"
EXCLUDE_ARGS="-x '*.git*' '.github/*'"
if [ -f ".releaseignore" ]; then
echo "🧾 使用 .releaseignore 过滤以下内容:"
while IFS= read -r line; do
if [ -n "$line" ] && [[ ! "$line" =~ ^# ]]; then
echo " - $line"
EXCLUDE_ARGS="$EXCLUDE_ARGS '$line'"
fi
done < .releaseignore
fi
eval zip -r "$ZIP_FILE" . $EXCLUDE_ARGS
echo "✅ 打包完成:$ZIP_FILE"
- name: Create GitHub Release
if: steps.check_release.outputs.skip_release == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.get_version.outputs.current_version }}
name: "v${{ steps.get_version.outputs.current_version }}"
body: "🔖 自动发布插件版本 v${{ steps.get_version.outputs.current_version }}"
files: |
${{ github.event.repository.name }}-${{ steps.get_version.outputs.current_version }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
文件位置:
.releaseignore
内容:
# 开发文件
.vscode/
.idea/
node_modules/
# 文档
README.md
screenshot.png
docs/
tests/
# GitHub Actions
.github/
.gitlab-ci.yml
# 系统文件
.DS_Store
Thumbs.db
*.log
注意
主题插件的文件命名、文件结构应符合WordPress规范,例如:
主题目录根目录应包含 style.css,开头注释应包含 “Version” 字段
插件名称为“My Good Plugin”,主插件文件应为 my-good-plugin.php,此文件头部应包含Version注释。
当任意提交push时,会首先检查版本号,如果与之前相同则不发布新版,不相同则自动打包发布,打包内容忽略.releaseignore内的所有文件或文件夹。