diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cc9a299a..3649cedd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -471,12 +471,12 @@ jobs: "release") echo "๐Ÿš€ Release build artifacts have been uploaded to OSS release directory" echo "โœ… This build is ready for production use" - echo "๐Ÿท๏ธ GitHub Release will be created automatically by the release workflow" + echo "๐Ÿท๏ธ GitHub Release will be created in this workflow" ;; "prerelease") echo "๐Ÿงช Prerelease build artifacts have been uploaded to OSS release directory" echo "โš ๏ธ This is a prerelease build - use with caution" - echo "๐Ÿท๏ธ GitHub Release will be created automatically by the release workflow" + echo "๐Ÿท๏ธ GitHub Release will be created in this workflow" ;; esac @@ -489,3 +489,264 @@ jobs: else echo "โŒ Docker image build will be skipped due to build failure" fi + + # Create GitHub Release (only for tag pushes) + create-release: + name: Create GitHub Release + needs: [build-check, build-rustfs] + if: startsWith(github.ref, 'refs/tags/') && needs.build-check.outputs.build_type != 'development' + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + release_id: ${{ steps.create.outputs.release_id }} + release_url: ${{ steps.create.outputs.release_url }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create GitHub Release + id: create + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ needs.build-check.outputs.version }}" + VERSION="${{ needs.build-check.outputs.version }}" + IS_PRERELEASE="${{ needs.build-check.outputs.is_prerelease }}" + BUILD_TYPE="${{ needs.build-check.outputs.build_type }}" + + # Determine release type for title + if [[ "$BUILD_TYPE" == "prerelease" ]]; then + if [[ "$TAG" == *"alpha"* ]]; then + RELEASE_TYPE="alpha" + elif [[ "$TAG" == *"beta"* ]]; then + RELEASE_TYPE="beta" + elif [[ "$TAG" == *"rc"* ]]; then + RELEASE_TYPE="rc" + else + RELEASE_TYPE="prerelease" + fi + else + RELEASE_TYPE="release" + fi + + # Check if release already exists + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists" + RELEASE_ID=$(gh release view "$TAG" --json databaseId --jq '.databaseId') + RELEASE_URL=$(gh release view "$TAG" --json url --jq '.url') + else + # Get release notes from tag message + RELEASE_NOTES=$(git tag -l --format='%(contents)' "${TAG}") + if [[ -z "$RELEASE_NOTES" || "$RELEASE_NOTES" =~ ^[[:space:]]*$ ]]; then + if [[ "$IS_PRERELEASE" == "true" ]]; then + RELEASE_NOTES="Pre-release ${VERSION} (${RELEASE_TYPE})" + else + RELEASE_NOTES="Release ${VERSION}" + fi + fi + + # Create release title + if [[ "$IS_PRERELEASE" == "true" ]]; then + TITLE="RustFS $VERSION (${RELEASE_TYPE})" + else + TITLE="RustFS $VERSION" + fi + + # Create the release + PRERELEASE_FLAG="" + if [[ "$IS_PRERELEASE" == "true" ]]; then + PRERELEASE_FLAG="--prerelease" + fi + + gh release create "$TAG" \ + --title "$TITLE" \ + --notes "$RELEASE_NOTES" \ + $PRERELEASE_FLAG \ + --draft + + RELEASE_ID=$(gh release view "$TAG" --json databaseId --jq '.databaseId') + RELEASE_URL=$(gh release view "$TAG" --json url --jq '.url') + fi + + echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT + echo "release_url=$RELEASE_URL" >> $GITHUB_OUTPUT + echo "Created release: $RELEASE_URL" + + # Prepare and upload release assets + upload-release-assets: + name: Upload Release Assets + needs: [build-check, build-rustfs, create-release] + if: startsWith(github.ref, 'refs/tags/') && needs.build-check.outputs.build_type != 'development' + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download all build artifacts + uses: actions/download-artifact@v4 + with: + path: ./artifacts + pattern: rustfs-* + merge-multiple: true + + - name: Prepare release assets + id: prepare + run: | + VERSION="${{ needs.build-check.outputs.version }}" + TAG="${{ needs.build-check.outputs.version }}" + + mkdir -p ./release-assets + + # Copy and verify artifacts + ASSETS_COUNT=0 + for file in ./artifacts/*.zip; do + if [[ -f "$file" ]]; then + cp "$file" ./release-assets/ + ASSETS_COUNT=$((ASSETS_COUNT + 1)) + fi + done + + if [[ $ASSETS_COUNT -eq 0 ]]; then + echo "โŒ No artifacts found!" + exit 1 + fi + + cd ./release-assets + + # Generate checksums + if ls *.zip >/dev/null 2>&1; then + sha256sum *.zip > SHA256SUMS + sha512sum *.zip > SHA512SUMS + fi + + # Create signature placeholder files + for file in *.zip; do + echo "# Signature for $file" > "${file}.asc" + echo "# GPG signature will be added in future versions" >> "${file}.asc" + done + + echo "๐Ÿ“ฆ Prepared assets:" + ls -la + + echo "๐Ÿ”ข Asset count: $ASSETS_COUNT" + + - name: Upload to GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ needs.build-check.outputs.version }}" + + cd ./release-assets + + # Upload all files + for file in *; do + if [[ -f "$file" ]]; then + echo "๐Ÿ“ค Uploading $file..." + gh release upload "$TAG" "$file" --clobber + fi + done + + echo "โœ… All assets uploaded successfully" + + # Update latest.json for stable releases only + update-latest-version: + name: Update Latest Version + needs: [build-check, upload-release-assets] + if: startsWith(github.ref, 'refs/tags/') && needs.build-check.outputs.is_prerelease == 'false' + runs-on: ubuntu-latest + steps: + - name: Update latest.json + env: + OSS_ACCESS_KEY_ID: ${{ secrets.ALICLOUDOSS_KEY_ID }} + OSS_ACCESS_KEY_SECRET: ${{ secrets.ALICLOUDOSS_KEY_SECRET }} + run: | + if [[ -z "$OSS_ACCESS_KEY_ID" ]]; then + echo "โš ๏ธ OSS credentials not available, skipping latest.json update" + exit 0 + fi + + VERSION="${{ needs.build-check.outputs.version }}" + TAG="${{ needs.build-check.outputs.version }}" + + # Install ossutil + OSSUTIL_VERSION="2.1.1" + OSSUTIL_ZIP="ossutil-${OSSUTIL_VERSION}-linux-amd64.zip" + OSSUTIL_DIR="ossutil-${OSSUTIL_VERSION}-linux-amd64" + + curl -o "$OSSUTIL_ZIP" "https://gosspublic.alicdn.com/ossutil/v2/${OSSUTIL_VERSION}/${OSSUTIL_ZIP}" + unzip "$OSSUTIL_ZIP" + chmod +x "${OSSUTIL_DIR}/ossutil" + + # Create latest.json + cat > latest.json << EOF + { + "version": "${VERSION}", + "tag": "${TAG}", + "release_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", + "release_type": "stable", + "download_url": "https://github.com/${{ github.repository }}/releases/tag/${TAG}" + } + EOF + + # Upload to OSS + ./${OSSUTIL_DIR}/ossutil cp latest.json oss://rustfs-version/latest.json --force + + echo "โœ… Updated latest.json for stable release $VERSION" + + # Publish release (remove draft status) + publish-release: + name: Publish Release + needs: [build-check, create-release, upload-release-assets] + if: startsWith(github.ref, 'refs/tags/') && needs.build-check.outputs.build_type != 'development' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Update release notes and publish + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG="${{ needs.build-check.outputs.version }}" + VERSION="${{ needs.build-check.outputs.version }}" + IS_PRERELEASE="${{ needs.build-check.outputs.is_prerelease }}" + BUILD_TYPE="${{ needs.build-check.outputs.build_type }}" + + # Determine release type + if [[ "$BUILD_TYPE" == "prerelease" ]]; then + if [[ "$TAG" == *"alpha"* ]]; then + RELEASE_TYPE="alpha" + elif [[ "$TAG" == *"beta"* ]]; then + RELEASE_TYPE="beta" + elif [[ "$TAG" == *"rc"* ]]; then + RELEASE_TYPE="rc" + else + RELEASE_TYPE="prerelease" + fi + else + RELEASE_TYPE="release" + fi + + # Get original release notes from tag + ORIGINAL_NOTES=$(git tag -l --format='%(contents)' "${TAG}") + if [[ -z "$ORIGINAL_NOTES" || "$ORIGINAL_NOTES" =~ ^[[:space:]]*$ ]]; then + if [[ "$IS_PRERELEASE" == "true" ]]; then + ORIGINAL_NOTES="Pre-release ${VERSION} (${RELEASE_TYPE})" + else + ORIGINAL_NOTES="Release ${VERSION}" + fi + fi + + # Publish the release (remove draft status) + gh release edit "$TAG" --draft=false + + echo "๐ŸŽ‰ Released $TAG successfully!" + echo "๐Ÿ“„ Release URL: ${{ needs.create-release.outputs.release_url }}" diff --git a/.github/workflows/release-notes-template.md b/.github/workflows/release-notes-template.md deleted file mode 100644 index efad0d67..00000000 --- a/.github/workflows/release-notes-template.md +++ /dev/null @@ -1,78 +0,0 @@ -## RustFS ${VERSION_CLEAN} - -${ORIGINAL_NOTES} - ---- - -### ๐Ÿš€ Quick Download - -**Linux (Static Binaries - No Dependencies):** - -```bash -# x86_64 (Intel/AMD) -curl -LO https://github.com/rustfs/rustfs/releases/download/${VERSION}/rustfs-x86_64-unknown-linux-musl.zip -unzip rustfs-x86_64-unknown-linux-musl.zip -sudo mv rustfs /usr/local/bin/ - -# ARM64 (Graviton, Apple Silicon VMs) -curl -LO https://github.com/rustfs/rustfs/releases/download/${VERSION}/rustfs-aarch64-unknown-linux-musl.zip -unzip rustfs-aarch64-unknown-linux-musl.zip -sudo mv rustfs /usr/local/bin/ -``` - -**macOS:** - -```bash -# Apple Silicon (M1/M2/M3) -curl -LO https://github.com/rustfs/rustfs/releases/download/${VERSION}/rustfs-aarch64-apple-darwin.zip -unzip rustfs-aarch64-apple-darwin.zip -sudo mv rustfs /usr/local/bin/ - -# Intel -curl -LO https://github.com/rustfs/rustfs/releases/download/${VERSION}/rustfs-x86_64-apple-darwin.zip -unzip rustfs-x86_64-apple-darwin.zip -sudo mv rustfs /usr/local/bin/ -``` - -### ๐Ÿ“ Available Downloads - -| Platform | Architecture | File | Description | -|----------|-------------|------|-------------| -| Linux | x86_64 | `rustfs-x86_64-unknown-linux-musl.zip` | Static binary, no dependencies | -| Linux | ARM64 | `rustfs-aarch64-unknown-linux-musl.zip` | Static binary, no dependencies | -| macOS | Apple Silicon | `rustfs-aarch64-apple-darwin.zip` | Native binary, ZIP archive | -| macOS | Intel | `rustfs-x86_64-apple-darwin.zip` | Native binary, ZIP archive | - -### ๐Ÿ” Verification - -Download checksums and verify your download: - -```bash -# Download checksums -curl -LO https://github.com/rustfs/rustfs/releases/download/${VERSION}/SHA256SUMS - -# Verify (Linux) -sha256sum -c SHA256SUMS --ignore-missing - -# Verify (macOS) -shasum -a 256 -c SHA256SUMS --ignore-missing -``` - -### ๐Ÿ› ๏ธ System Requirements - -- **Linux**: Any distribution with glibc 2.17+ (CentOS 7+, Ubuntu 16.04+) -- **macOS**: 10.15+ (Catalina or later) -- **Windows**: Windows 10 version 1809 or later - -### ๐Ÿ“š Documentation - -- [Installation Guide](https://github.com/rustfs/rustfs#installation) -- [Quick Start](https://github.com/rustfs/rustfs#quick-start) -- [Configuration](https://github.com/rustfs/rustfs/blob/main/docs/) -- [API Documentation](https://docs.rs/rustfs) - -### ๐Ÿ†˜ Support - -- ๐Ÿ› [Report Issues](https://github.com/rustfs/rustfs/issues) -- ๐Ÿ’ฌ [Community Discussions](https://github.com/rustfs/rustfs/discussions) -- ๐Ÿ“– [Documentation](https://github.com/rustfs/rustfs/tree/main/docs) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4490f3d9..6f3392b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,19 +12,31 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Release +# โš ๏ธ DEPRECATED: This workflow has been deprecated +# Release logic has been merged into build.yml to avoid cross-workflow artifact access issues. +# This file is kept for reference but is no longer active. + +name: Release (Deprecated) on: - # Automatically triggered when build workflow completes successfully - workflow_run: - workflows: ["Build and Release"] - types: [completed] - branches: [main] - # Manual trigger for standalone release creation + # Disabled - release logic is now in build.yml + # workflow_run: + # workflows: ["Build and Release"] + # types: [completed] + # branches: [main] + # Manual trigger for standalone release creation (disabled) + # workflow_dispatch: + # inputs: + # tag: + # description: "Tag to create release for" + # required: true + # type: string + + # This workflow is disabled - only manual trigger with specific confirmation workflow_dispatch: inputs: - tag: - description: "Tag to create release for" + confirm_deprecated: + description: "This workflow is deprecated. Type 'CONFIRM' to run anyway." required: true type: string @@ -32,9 +44,32 @@ env: CARGO_TERM_COLOR: always jobs: + # Warning job to inform users this workflow is deprecated + deprecated-warning: + name: โš ๏ธ Deprecated Workflow Warning + runs-on: ubuntu-latest + steps: + - name: Display deprecation warning + run: | + echo "๐Ÿšจ WARNING: This workflow has been DEPRECATED ๐Ÿšจ" + echo "" + echo "Release functionality has been moved to the build.yml workflow" + echo "to resolve cross-workflow artifact access issues." + echo "" + echo "Please use tag pushes to trigger releases automatically via build.yml" + echo "" + if [[ "${{ github.event.inputs.confirm_deprecated }}" != "CONFIRM" ]]; then + echo "โŒ To run this deprecated workflow anyway, you must type 'CONFIRM' in the input field." + echo "โš ๏ธ However, this workflow may not work correctly due to artifact access limitations." + exit 1 + fi + echo "โš ๏ธ Proceeding with deprecated workflow as requested..." + # Determine release type and check if we should proceed release-check: name: Release Type Check + needs: deprecated-warning + if: github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest outputs: tag: ${{ steps.check.outputs.tag }} @@ -133,7 +168,7 @@ jobs: create-release: name: Create GitHub Release needs: release-check - if: needs.release-check.outputs.should_release == 'true' + if: needs.release-check.outputs.should_release == 'true' && github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest permissions: contents: write @@ -203,6 +238,7 @@ jobs: prepare-assets: name: Prepare Release Assets needs: [release-check, create-release] + if: github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest permissions: contents: read @@ -367,6 +403,7 @@ jobs: upload-assets: name: Upload Release Assets needs: [release-check, create-release, prepare-assets] + if: github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest permissions: contents: write @@ -399,7 +436,7 @@ jobs: update-latest: name: Update Latest Version needs: [release-check, upload-assets] - if: needs.release-check.outputs.is_prerelease == 'false' + if: needs.release-check.outputs.is_prerelease == 'false' && github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest steps: - name: Update latest.json @@ -444,6 +481,7 @@ jobs: publish-release: name: Publish Release needs: [release-check, create-release, upload-assets] + if: github.event.inputs.confirm_deprecated == 'CONFIRM' runs-on: ubuntu-latest permissions: contents: write @@ -470,17 +508,7 @@ jobs: fi fi - # Use release notes template if available - if [[ -f ".github/workflows/release-notes-template.md" ]]; then - # Substitute variables in template - sed -e "s/\${VERSION}/$TAG/g" \ - -e "s/\${VERSION_CLEAN}/$VERSION/g" \ - -e "s/\${ORIGINAL_NOTES}/$(echo "$ORIGINAL_NOTES" | sed 's/[[\.*^$()+?{|]/\\&/g')/g" \ - .github/workflows/release-notes-template.md > enhanced_notes.md - # Update release notes - gh release edit "$TAG" --notes-file enhanced_notes.md - fi # Publish the release (remove draft status) gh release edit "$TAG" --draft=false