diff --git a/.github/workflows/node.js.yml.disabled b/.github/workflows/node.js.yml.disabled deleted file mode 100644 index e2e9e08..0000000 --- a/.github/workflows/node.js.yml.disabled +++ /dev/null @@ -1,56 +0,0 @@ -name: Node.js CI - -on: - pull_request: - branches: [main] - push: - branches: [main] -permissions: - contents: read - -jobs: - test: - name: Test - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x, 18.x, 22.x] - steps: - - uses: actions/checkout@v5 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v6 - with: - node-version: ${{ matrix.node-version }} - # Use built-in package manager cache for pnpm - cache: 'pnpm' - cache-dependency-path: '**/pnpm-lock.yaml' - - name: Install pnpm - run: npm install -g pnpm - - name: Install dependencies (pnpm) - run: pnpm install --frozen-lockfile - - name: Test - env: - NCM_API_TEST_LOGIN_COUNTRY_CODE: ${{ secrets.NCM_API_TEST_LOGIN_COUNTRY_CODE }} - NCM_API_TEST_LOGIN_PHONE: ${{ secrets.NCM_API_TEST_LOGIN_PHONE }} - NCM_API_TEST_LOGIN_PASSWORD: ${{ secrets.NCM_API_TEST_LOGIN_PASSWORD }} - run: pnpm test - lint: - name: Lint - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x] - steps: - - uses: actions/checkout@v5 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v6 - with: - node-version: ${{ matrix.node-version }} - cache: 'pnpm' - cache-dependency-path: '**/pnpm-lock.yaml' - - name: Install pnpm - run: npm install -g pnpm - - name: Install dependencies (pnpm) - run: pnpm install --frozen-lockfile - - name: Lint - run: pnpm run lint diff --git a/.github/workflows/release-on-version-change.yml b/.github/workflows/release-on-version-change.yml new file mode 100644 index 0000000..e29d51c --- /dev/null +++ b/.github/workflows/release-on-version-change.yml @@ -0,0 +1,231 @@ +name: Create Release on Version Change + +on: + push: + branches: + - main + paths: + - package.json + + workflow_dispatch: + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + detect: + name: Detect Version Change + runs-on: ubuntu-latest + + outputs: + version: ${{ steps.version.outputs.value }} + should_release: ${{ steps.check.outputs.should_release }} + tag_exists: ${{ steps.tagcheck.outputs.exists }} + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Extract version from package.json + id: version + run: | + echo "value=$(jq -r .version package.json)" >> $GITHUB_OUTPUT + + - name: Check if version changed + id: check + shell: bash + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "should_release=true" >> $GITHUB_OUTPUT + exit 0 + fi + + if git diff "${{ github.event.before }}" "${{ github.sha }}" -- package.json | grep -q '"version"'; then + echo "should_release=true" >> $GITHUB_OUTPUT + else + echo "should_release=false" >> $GITHUB_OUTPUT + fi + + - name: Check if tag already exists + id: tagcheck + shell: bash + run: | + VERSION="${{ steps.version.outputs.value }}" + + if git rev-parse "v$VERSION" >/dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "exists=false" >> $GITHUB_OUTPUT + fi + + build: + name: Build ${{ matrix.platform }} + needs: detect + + if: | + needs.detect.outputs.should_release == 'true' && + needs.detect.outputs.tag_exists != 'true' + + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + + matrix: + include: + - os: ubuntu-latest + platform: linux + target: node18-linux-x64 + output: ncm-api-linux-x64 + + - os: windows-latest + platform: windows + target: node18-win-x64 + output: ncm-api-win-x64.exe + + - os: macos-latest + platform: macos + target: node18-macos-x64 + output: ncm-api-macos-x64 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 18 + cache: pnpm + + - name: Setup pnpm + uses: pnpm/action-setup@v6 + with: + version: 9 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build binary + shell: bash + env: + PKG_TARGET: ${{ matrix.target }} + run: | + mkdir -p release-artifacts + + case "${{ matrix.platform }}" in + linux) + npm run pkglinux + mv precompiled/app "release-artifacts/${{ matrix.output }}" + ;; + + windows) + npm run pkgwin + mv precompiled/app.exe "release-artifacts/${{ matrix.output }}" + ;; + + macos) + npm run pkgmacos + mv precompiled/app "release-artifacts/${{ matrix.output }}" + ;; + esac + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.platform }}-binary + path: release-artifacts/* + + release: + name: Create GitHub Release + + needs: + - detect + - build + + if: | + needs.detect.outputs.should_release == 'true' && + needs.detect.outputs.tag_exists != 'true' + + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + path: release-artifacts + + - name: Flatten artifacts + shell: bash + run: | + mkdir -p final-artifacts + + find release-artifacts -type f -exec cp {} final-artifacts/ \; + + ls -lah final-artifacts + + - name: Generate release notes + shell: bash + run: | + VERSION="${{ needs.detect.outputs.version }}" + + PREV_TAG=$(git tag --sort=-v:refname | head -1) + + { + echo "# Release v${VERSION}" + echo "" + echo "## 更新内容 / Changelog" + echo "" + + if [ -n "$PREV_TAG" ]; then + echo "从 \`$PREV_TAG\` 到 \`v$VERSION\` 的提交记录:" + echo "" + + git log "$PREV_TAG..HEAD" \ + --no-merges \ + --pretty=format:"- %s (%h)" + + else + echo "首次发布,包含以下提交:" + echo "" + + git log \ + --no-merges \ + --pretty=format:"- %s (%h)" + fi + + echo "" + echo "" + echo "---" + echo "自动发布 via GitHub Actions" + + } > release-notes.md + + cat release-notes.md + + - name: Create Git tag + run: | + git tag "v${{ needs.detect.outputs.version }}" + git push origin "v${{ needs.detect.outputs.version }}" + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ needs.detect.outputs.version }} + name: Release v${{ needs.detect.outputs.version }} + body_path: release-notes.md + files: final-artifacts/* + draft: false + prerelease: false \ No newline at end of file