merge: release/20260519 → main (wecom v2026.5.12) #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release & Publish | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| - 'wecom-v*' | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| # 🌟 必须与 npm 设置的 Environment 一致 | |
| environment: release | |
| permissions: | |
| contents: write # 发布 Release | |
| id-token: write # 获取 OIDC 身份令牌 | |
| packages: write # 发布到 GitHub Packages(npm.pkg.github.com) | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| # npm Trusted Publishing (OIDC) requires npm >=11.5.1. | |
| # Use Node 24 to get modern npm in hosted runners. | |
| node-version: '24' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Show runtime versions | |
| run: | | |
| node -v | |
| npm -v | |
| - name: Ensure npm trusted publishing support | |
| run: | | |
| npm i -g npm@^11.5.1 | |
| npm -v | |
| npm config delete always-auth || true | |
| - name: Resolve release metadata | |
| id: meta | |
| run: | | |
| set -euo pipefail | |
| TAG="${GITHUB_REF_NAME}" | |
| if [[ "${TAG}" == wecom-v* ]]; then | |
| VERSION="${TAG#wecom-v}" | |
| elif [[ "${TAG}" == v* ]]; then | |
| VERSION="${TAG#v}" | |
| else | |
| echo "::error::Unsupported tag format: ${TAG}. Use v<version> or wecom-v<version>." | |
| exit 1 | |
| fi | |
| PKG_NAME="$(node -p "require('./package.json').name")" | |
| PKG_VERSION="$(node -p "require('./package.json').version")" | |
| echo "tag=${TAG}" >> "$GITHUB_OUTPUT" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "pkg_name=${PKG_NAME}" >> "$GITHUB_OUTPUT" | |
| echo "pkg_version=${PKG_VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${TAG}" | |
| echo "version_from_tag=${VERSION}" | |
| echo "package=${PKG_NAME}@${PKG_VERSION}" | |
| if [ "${VERSION}" != "${PKG_VERSION}" ]; then | |
| echo "::error::Tag version (${VERSION}) does not match package.json version (${PKG_VERSION})." | |
| exit 1 | |
| fi | |
| - name: Check npm version already published | |
| id: npm_check | |
| run: | | |
| set -euo pipefail | |
| PKG="${{ steps.meta.outputs.pkg_name }}" | |
| VER="${{ steps.meta.outputs.pkg_version }}" | |
| if npm view "${PKG}@${VER}" version >/dev/null 2>&1; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "npm version already published: ${PKG}@${VER}" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "npm version not published yet: ${PKG}@${VER}" | |
| fi | |
| - name: Install Dependencies | |
| run: npm install --legacy-peer-deps || npm install | |
| - name: Build Plugin | |
| run: npm run build --if-present | |
| # 🚀 自动发布到 npm (使用 OIDC 自动授权,无需 Token) | |
| - name: Publish to npm | |
| if: steps.npm_check.outputs.exists != 'true' | |
| run: npm publish --access public | |
| - name: Setup Node.js for GitHub Packages | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| registry-url: 'https://npm.pkg.github.com' | |
| scope: '@${{ github.repository_owner }}' | |
| # GitHub npm registry requires scope == repository owner. Publish under @${owner}/<basename> | |
| # while npmjs keeps the original package name (e.g. @mocrane/wecom). | |
| - name: Publish to GitHub Packages | |
| env: | |
| NODE_AUTH_TOKEN: ${{ github.token }} | |
| OWNER: ${{ github.repository_owner }} | |
| run: | | |
| set -euo pipefail | |
| OWNER_LC="$(echo "${OWNER}" | tr '[:upper:]' '[:lower:]')" | |
| ORIG_PKG=$(node -p "require('./package.json').name") | |
| VERSION=$(node -p "require('./package.json').version") | |
| case "${ORIG_PKG}" in | |
| @*/*) ;; | |
| *) | |
| echo "::error::Expected scoped package name, got: ${ORIG_PKG}" | |
| exit 1 | |
| ;; | |
| esac | |
| BASE="${ORIG_PKG##*/}" | |
| GH_PKG="@${OWNER_LC}/${BASE}" | |
| REG="https://npm.pkg.github.com" | |
| SPEC="${GH_PKG}@${VERSION}" | |
| if npm view "${SPEC}" version --registry "${REG}" >/dev/null 2>&1; then | |
| echo "::notice::${SPEC} already exists on GitHub Packages, skip." | |
| exit 0 | |
| fi | |
| cp -a package.json package.json.orig | |
| restore_pkg() { | |
| if [ -f package.json.orig ]; then | |
| mv -f package.json.orig package.json | |
| fi | |
| } | |
| trap restore_pkg EXIT | |
| if [ "${ORIG_PKG}" != "${GH_PKG}" ]; then | |
| echo "::notice::GitHub Packages publish as ${GH_PKG} (npmjs remains ${ORIG_PKG})." | |
| node -e "const fs=require('fs');const n=process.argv[1];const j=JSON.parse(fs.readFileSync('package.json','utf8'));j.name=n;fs.writeFileSync('package.json',JSON.stringify(j,null,2)+'\n');" "${GH_PKG}" | |
| fi | |
| npm whoami --registry "${REG}" | |
| set +e | |
| npm publish --registry "${REG}" --access public 2>&1 | tee publish-gh.log | |
| PUBLISH_EXIT=${PIPESTATUS[0]} | |
| set -e | |
| if [ "${PUBLISH_EXIT}" -eq 0 ]; then | |
| echo "::notice::Published ${SPEC} to GitHub Packages." | |
| restore_pkg | |
| trap - EXIT | |
| exit 0 | |
| fi | |
| if grep -Eqi 'cannot publish over the previously published versions|You cannot publish over the previously published versions|code E409|409 Conflict|already exists' publish-gh.log; then | |
| echo "::notice::${SPEC} appears already published on GitHub Packages (detected from publish output), treating as skip." | |
| restore_pkg | |
| trap - EXIT | |
| exit 0 | |
| fi | |
| echo "::error::npm publish to GitHub Packages failed (exit ${PUBLISH_EXIT})." | |
| exit "${PUBLISH_EXIT}" | |
| - name: Prepare release notes body | |
| id: notes | |
| run: | | |
| set -euo pipefail | |
| CHANGELOG_FILE="changelog/v${{ steps.meta.outputs.version }}.md" | |
| if [ -f "${CHANGELOG_FILE}" ]; then | |
| echo "Using changelog file: ${CHANGELOG_FILE}" | |
| cp "${CHANGELOG_FILE}" /tmp/release-body.md | |
| else | |
| echo "Changelog file missing: ${CHANGELOG_FILE}; using fallback notes." | |
| { | |
| echo "# @yanhaidao/wecom v${{ steps.meta.outputs.version }}" | |
| echo | |
| if [ "${{ steps.npm_check.outputs.exists }}" = "true" ]; then | |
| echo "- npm publish skipped: version already exists." | |
| else | |
| echo "- npm publish completed." | |
| fi | |
| } > /tmp/release-body.md | |
| fi | |
| # 自动同步发布 GitHub Release | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| body_path: /tmp/release-body.md | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |