From 604165611feac1d5265fbc2831ea11c2d5544117 Mon Sep 17 00:00:00 2001 From: Leon Zhao Date: Sun, 7 Sep 2025 10:38:20 +0800 Subject: [PATCH] chore: new release ci --- .github/workflows/pre-release.yaml | 49 ++++++--- .github/workflows/release-on-merge.yaml | 134 ++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/release-on-merge.yaml diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml index b36f222..361d441 100644 --- a/.github/workflows/pre-release.yaml +++ b/.github/workflows/pre-release.yaml @@ -1,10 +1,15 @@ -name: Pre-release Build and Publish +name: Pre-release Build and PR +run-name: Pre-release ${{ github.ref_name }} on: push: tags: - '*-pre-release' +permissions: + contents: write + pull-requests: write + jobs: build-and-release: runs-on: macos-latest @@ -34,6 +39,12 @@ jobs: CHECKSUM=$(openssl dgst -sha256 loroFFI.xcframework.zip | awk '{print $2}') echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT + - name: Upload XCFramework artifact + uses: actions/upload-artifact@v4 + with: + name: loroFFI.xcframework.zip + path: loroFFI.xcframework.zip + - name: Update Package.swift run: | VERSION=${{ steps.get_version.outputs.version }} @@ -50,25 +61,31 @@ jobs: -e "s|\"https://github.com/loro-dev/loro-swift.git\", from: \"[0-9.]*\"|\"https://github.com/loro-dev/loro-swift.git\", from: \"${VERSION}\"|" \ README.md - - name: Commit and push changes + - name: Commit and push changes to pre-release branch run: | VERSION=${{ steps.get_version.outputs.version }} git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" + # Ensure local pre-release branch points to current commit + git fetch origin pre-release:pre-release || true + git checkout -B pre-release "$GITHUB_SHA" git add Package.swift README.md Sources/* - git commit -m "chore: update version to ${VERSION}" - git tag -a "${VERSION}" -m "Release version ${VERSION}" - git push origin HEAD:main - git push origin "${VERSION}" + git commit -m "chore: update version to ${VERSION}" || echo "No changes to commit" + git push origin pre-release - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.get_version.outputs.version }} - name: Release ${{ steps.get_version.outputs.version }} - files: loroFFI.xcframework.zip - draft: false - prerelease: false - generate_release_notes: true + - name: Create or update Pull Request to main env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + VERSION=${{ steps.get_version.outputs.version }} + CHECKSUM=${{ steps.sha256.outputs.checksum }} + PR_NUMBER=$(gh pr list --base main --head pre-release --state open --json number --jq '.[0].number') + if [ -z "$PR_NUMBER" ]; then + gh pr create \ + --base main \ + --head pre-release \ + --title "Release ${VERSION}" \ + --body "This PR updates Package.swift and README.md to version ${VERSION}.\n\nSHA256 checksum: ${CHECKSUM}.\n\nThe XCFramework artifact has been uploaded to this workflow run." + else + echo "PR #$PR_NUMBER already exists." + fi diff --git a/.github/workflows/release-on-merge.yaml b/.github/workflows/release-on-merge.yaml new file mode 100644 index 0000000..03d93bf --- /dev/null +++ b/.github/workflows/release-on-merge.yaml @@ -0,0 +1,134 @@ +name: Create Release on Merge + +on: + pull_request: + types: [closed] + +permissions: + contents: write + pull-requests: read + actions: read + +jobs: + create-release: + if: >- + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' && + github.event.pull_request.head.ref == 'pre-release' + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine version from Package.swift + id: get_version + shell: bash + run: | + VERSION=$(grep -o 'releases/download/[^/]*/loroFFI\.xcframework\.zip' Package.swift | sed 's|releases/download/||' | sed 's|/loroFFI\.xcframework\.zip||' | head -n1) + if [ -z "$VERSION" ]; then + echo "Failed to determine version from Package.swift" >&2 + exit 1 + fi + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Determine merge commit + id: get_sha + shell: bash + run: | + SHA="${{ github.event.pull_request.merge_commit_sha }}" + if [ -z "$SHA" ]; then + echo "Merge commit sha is empty" >&2 + exit 1 + fi + echo "sha=$SHA" >> $GITHUB_OUTPUT + + - name: Find pre-release workflow run and download artifact + shell: bash + run: | + VERSION=${{ steps.get_version.outputs.version }} + TAG_NAME="${VERSION}-pre-release" + + echo "Looking for workflow run for tag: $TAG_NAME" + + # Get the commit SHA of the tag + TAG_SHA="" + if git rev-parse --verify "$TAG_NAME" >/dev/null 2>&1; then + TAG_SHA=$(git rev-parse "$TAG_NAME") + echo "Tag $TAG_NAME points to commit: $TAG_SHA" + fi + + # Find workflow runs and check multiple criteria + RUNS_JSON=$(gh run list \ + --workflow "Pre-release Build and PR" \ + --status success \ + --limit 20 \ + --json databaseId,headSha,displayTitle,createdAt) + + RUN_ID="" + + # Method 1: Try to match by tag SHA + if [ -n "$TAG_SHA" ]; then + RUN_ID=$(echo "$RUNS_JSON" | jq -r ".[] | select(.headSha == \"$TAG_SHA\") | .databaseId" | head -n1) + if [ -n "$RUN_ID" ]; then + echo "Found run by SHA match: $RUN_ID" + fi + fi + + # Method 2: Try to match by displayTitle + if [ -z "$RUN_ID" ]; then + RUN_ID=$(echo "$RUNS_JSON" | jq -r ".[] | select(.displayTitle == \"Pre-release $TAG_NAME\") | .databaseId" | head -n1) + if [ -n "$RUN_ID" ]; then + echo "Found run by displayTitle match: $RUN_ID" + fi + fi + + # Method 3: Use the most recent successful run as fallback + if [ -z "$RUN_ID" ]; then + RUN_ID=$(echo "$RUNS_JSON" | jq -r '.[0].databaseId') + if [ -n "$RUN_ID" ]; then + echo "Using most recent successful run as fallback: $RUN_ID" + fi + fi + + if [ -z "$RUN_ID" ]; then + echo "Could not find any suitable workflow run" >&2 + exit 1 + fi + + gh run download "$RUN_ID" --name loroFFI.xcframework.zip --dir . + # Normalize location if downloaded into a directory + if [ -d loroFFI.xcframework.zip ] && [ -f loroFFI.xcframework.zip/loroFFI.xcframework.zip ]; then + mv loroFFI.xcframework.zip/loroFFI.xcframework.zip . + rm -rf loroFFI.xcframework.zip + fi + if [ ! -f loroFFI.xcframework.zip ]; then + echo "Artifact loroFFI.xcframework.zip not found after download" >&2 + exit 1 + fi + + - name: Create tag on merge commit + shell: bash + run: | + VERSION=${{ steps.get_version.outputs.version }} + SHA=${{ steps.get_sha.outputs.sha }} + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + # Create or move tag to the merge commit + if git rev-parse "$VERSION" >/dev/null 2>&1; then + git tag -d "$VERSION" + fi + git tag -a "$VERSION" -m "Release version $VERSION" "$SHA" + git push --force origin "$VERSION" + + - name: Create GitHub Release + shell: bash + run: | + VERSION=${{ steps.get_version.outputs.version }} + gh release create "$VERSION" loroFFI.xcframework.zip \ + --title "Release $VERSION" \ + --notes "Automated release for version $VERSION. Includes pre-built loroFFI.xcframework.zip." +