diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index e9d4206..da20824 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -49,29 +49,69 @@ jobs: echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT echo "Building version: ${VERSION}" - - name: Build scorex for Linux (x86_64) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_linux_amd64 + - name: Build scorex for all platforms + run: | + VERSION=${{ steps.version.outputs.VERSION }} bazel build \ + //scorex:scorex_linux_amd64 \ + //scorex:scorex_darwin_arm64 \ + //scorex:scorex_windows_amd64 - - name: Copy Linux binary + - name: Copy binaries to artifacts run: | mkdir -p artifacts - cp bazel-bin/scorex/scorex_linux_amd64_/scorex_linux_amd64 artifacts/scorex-linux-x86_64 - - name: Build scorex for macOS (Apple Silicon) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_darwin_arm64 + # Use bazel cquery to find actual output paths (bazel-bin symlink is cleared for multi-platform builds) + echo "Finding binary locations..." + LINUX_BIN=$(bazel cquery --output=files //scorex:scorex_linux_amd64 2>/dev/null) + DARWIN_ARM64_BIN=$(bazel cquery --output=files //scorex:scorex_darwin_arm64 2>/dev/null) + WINDOWS_BIN=$(bazel cquery --output=files //scorex:scorex_windows_amd64 2>/dev/null) + + echo "Linux binary: $LINUX_BIN" + echo "macOS ARM64 binary: $DARWIN_ARM64_BIN" + echo "Windows binary: $WINDOWS_BIN" + + # Copy binaries + if [ -f "$LINUX_BIN" ]; then + cp "$LINUX_BIN" artifacts/scorex-linux-x86_64 + echo "✓ Linux binary copied" + else + echo "ERROR: Linux binary not found at $LINUX_BIN" + exit 1 + fi + + if [ -f "$DARWIN_ARM64_BIN" ]; then + cp "$DARWIN_ARM64_BIN" artifacts/scorex-macos-arm64 + echo "✓ macOS ARM64 binary copied" + else + echo "ERROR: macOS ARM64 binary not found" + exit 1 + fi - - name: Copy macOS binary - run: cp bazel-bin/scorex/scorex_darwin_arm64_/scorex_darwin_arm64 artifacts/scorex-macos-arm64 + if [ -f "$WINDOWS_BIN" ]; then + cp "$WINDOWS_BIN" artifacts/scorex-windows-x86_64.exe + echo "✓ Windows binary copied" + else + echo "ERROR: Windows binary not found" + exit 1 + fi - - name: Build scorex for Windows (x86_64) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_windows_amd64 + - name: Upload Linux artifacts + uses: actions/upload-artifact@v4 + with: + name: scorex-linux + path: artifacts/scorex-linux-x86_64 + if-no-files-found: error - - name: Copy Windows binary - run: cp bazel-bin/scorex/scorex_windows_amd64_/scorex_windows_amd64.exe artifacts/scorex-windows-x86_64.exe + - name: Upload macOS artifacts + uses: actions/upload-artifact@v4 + with: + name: scorex-macos + path: artifacts/scorex-macos-arm64 + if-no-files-found: error - - name: Upload CLI artifacts + - name: Upload Windows artifacts uses: actions/upload-artifact@v4 with: - name: scorex-cli-${{ steps.version.outputs.VERSION }} - path: artifacts/ + name: scorex-windows + path: artifacts/scorex-windows-x86_64.exe if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 356d1ce..db00a05 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,17 @@ on: push: tags: - 'v*' + workflow_dispatch: + inputs: + version: + description: 'Version to use for test release (e.g., 0.1.0-test)' + required: false + default: '0.0.0-test' + pull_request: + types: [opened, reopened, synchronize] + paths: + - 'scorex/**' + - '.github/workflows/release.yml' jobs: build-and-release: @@ -39,30 +50,96 @@ jobs: - name: Get version from tag id: version run: | - VERSION=${GITHUB_REF#refs/tags/v} + if [ "${{ github.event_name }}" == "push" ] && [ -n "${{ github.ref }}" ]; then + # Release from tag + VERSION=${GITHUB_REF#refs/tags/v} + TAG=${GITHUB_REF#refs/tags/} + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Manual test release + VERSION="${{ github.event.inputs.version }}" + TAG="test-${VERSION}" + else + # PR test release + SHORT_SHA=$(git rev-parse --short HEAD) + VERSION="pr-${{ github.event.pull_request.number }}-${SHORT_SHA}" + TAG="test-${VERSION}" + fi echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + echo "TAG=${TAG}" >> $GITHUB_OUTPUT echo "Building version: ${VERSION}" - - name: Build scorex for Linux (x86_64) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_linux_amd64 - - - name: Build scorex for macOS (Apple Silicon) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_darwin_arm64 - - - name: Build scorex for macOS (Intel) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_darwin_amd64 + - name: Build scorex for all platforms + run: | + echo "Current directory: $(pwd)" + echo "Building all platforms..." + VERSION=${{ steps.version.outputs.VERSION }} bazel build \ + //scorex:scorex_linux_amd64 \ + //scorex:scorex_darwin_arm64 \ + //scorex:scorex_darwin_amd64 \ + //scorex:scorex_windows_amd64 + echo "Build complete. Exit code: $?" - - name: Build scorex for Windows (x86_64) - run: VERSION=${{ steps.version.outputs.VERSION }} bazel build //scorex:scorex_windows_amd64 + - name: Debug bazel output + run: | + echo "=== Current directory ===" + pwd + echo "=== Listing current directory ===" + ls -la + echo "=== Checking for bazel-bin symlink ===" + ls -la | grep bazel || echo "No bazel symlinks found" + echo "=== Searching for bazel output ===" + find . -type d -name "bazel-bin" 2>/dev/null || echo "bazel-bin directory not found" + echo "=== Searching for scorex binaries ===" + find . -name "scorex_linux_amd64" -type f 2>/dev/null || echo "No Linux binary found" - name: Prepare release artifacts run: | mkdir -p release - cp bazel-bin/scorex/scorex_linux_amd64_/scorex_linux_amd64 release/scorex-linux-x86_64 - cp bazel-bin/scorex/scorex_darwin_arm64_/scorex_darwin_arm64 release/scorex-macos-arm64 - cp bazel-bin/scorex/scorex_darwin_amd64_/scorex_darwin_amd64 release/scorex-macos-x86_64 - cp bazel-bin/scorex/scorex_windows_amd64_/scorex_windows_amd64.exe release/scorex-windows-x86_64.exe + + # Use bazel cquery to find actual output paths (bazel-bin symlink is cleared for multi-platform builds) + echo "Finding binary locations..." + LINUX_BIN=$(bazel cquery --output=files //scorex:scorex_linux_amd64 2>/dev/null) + DARWIN_ARM64_BIN=$(bazel cquery --output=files //scorex:scorex_darwin_arm64 2>/dev/null) + DARWIN_AMD64_BIN=$(bazel cquery --output=files //scorex:scorex_darwin_amd64 2>/dev/null) + WINDOWS_BIN=$(bazel cquery --output=files //scorex:scorex_windows_amd64 2>/dev/null) + + echo "Linux binary: $LINUX_BIN" + echo "macOS ARM64 binary: $DARWIN_ARM64_BIN" + echo "macOS AMD64 binary: $DARWIN_AMD64_BIN" + echo "Windows binary: $WINDOWS_BIN" + + # Copy binaries + if [ -f "$LINUX_BIN" ]; then + cp "$LINUX_BIN" release/scorex-linux-x86_64 + echo "✓ Linux binary copied" + else + echo "ERROR: Linux binary not found at $LINUX_BIN" + exit 1 + fi + + if [ -f "$DARWIN_ARM64_BIN" ]; then + cp "$DARWIN_ARM64_BIN" release/scorex-macos-arm64 + echo "✓ macOS ARM64 binary copied" + else + echo "ERROR: macOS ARM64 binary not found" + exit 1 + fi + + if [ -f "$DARWIN_AMD64_BIN" ]; then + cp "$DARWIN_AMD64_BIN" release/scorex-macos-x86_64 + echo "✓ macOS AMD64 binary copied" + else + echo "ERROR: macOS AMD64 binary not found" + exit 1 + fi + + if [ -f "$WINDOWS_BIN" ]; then + cp "$WINDOWS_BIN" release/scorex-windows-x86_64.exe + echo "✓ Windows binary copied" + else + echo "ERROR: Windows binary not found" + exit 1 + fi # Create compressed archives cd release @@ -75,6 +152,8 @@ jobs: sha256sum *.tar.gz *.zip > checksums.txt - name: Create Release + # Only create actual release on tag push + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v1 with: files: | @@ -86,3 +165,30 @@ jobs: generate_release_notes: true draft: false prerelease: false + + - name: Upload Linux artifacts + # Upload artifacts for PRs and manual runs + if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: scorex-linux + path: release/scorex-${{ steps.version.outputs.VERSION }}-linux-x86_64.tar.gz + retention-days: 7 + + - name: Upload macOS artifacts + if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: scorex-macos + path: | + release/scorex-${{ steps.version.outputs.VERSION }}-macos-arm64.tar.gz + release/scorex-${{ steps.version.outputs.VERSION }}-macos-x86_64.tar.gz + retention-days: 7 + + - name: Upload Windows artifacts + if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/') + uses: actions/upload-artifact@v4 + with: + name: scorex-windows + path: release/scorex-${{ steps.version.outputs.VERSION }}-windows-x86_64.zip + retention-days: 7 diff --git a/scorex/README.md b/scorex/README.md index 6918902..e547964 100644 --- a/scorex/README.md +++ b/scorex/README.md @@ -80,37 +80,31 @@ The `init` command (see [scorex/cmd/init.go](scorex/cmd/init.go)) supports: ## Distribution -The `scorex` CLI is distributed through multiple package managers for easy installation across different platforms. - ### Installation Methods -#### macOS & Linux - Homebrew +#### Install Script (Recommended) +**macOS & Linux:** ```bash -# Add the tap (once a tap repository is created) -brew tap eclipse-score/tap - -# Install scorex -brew install scorex +curl -sSL https://raw.githubusercontent.com/eclipse-score/score_scrample/main/scorex/distribution/install.sh | sh ``` -#### Windows - Scoop - -```bash -# Add the bucket (once a bucket repository is created) -scoop bucket add eclipse-score https://github.com/eclipse-score/scoop-bucket - -# Install scorex -scoop install scorex -``` +**Note**: Requires a published release. If no releases exist yet, use manual installation below. -#### Universal - Install Script +This script automatically: +- Detects your OS and architecture +- Downloads the correct binary from the latest release +- Installs it to `$HOME/.local/bin/scorex` (customizable via `SCOREX_INSTALL_DIR`) +- Makes it executable +- Removes macOS quarantine attribute automatically -**macOS & Linux:** +**Add to PATH** (if not already): ```bash -curl -sSL https://raw.githubusercontent.com/eclipse-score/score_scrample/main/scorex/distribution/install.sh | sh +export PATH="$HOME/.local/bin:$PATH" ``` +Add this to your `~/.zshrc` or `~/.bashrc` to make it permanent. + #### Manual Download Download the appropriate binary for your platform from the [releases page](https://github.com/eclipse-score/score_scrample/releases): @@ -120,59 +114,86 @@ Download the appropriate binary for your platform from the [releases page](https - **macOS (Intel)**: `scorex-VERSION-macos-x86_64.tar.gz` - **Windows (x86_64)**: `scorex-VERSION-windows-x86_64.zip` -Extract and move to a directory in your PATH. +**Installation steps:** -### For Maintainers +1. Download the appropriate archive for your platform +2. Extract it: + ```bash + # macOS/Linux + tar -xzf scorex-VERSION-platform.tar.gz -#### Publishing a New Release + # Windows (PowerShell) + Expand-Archive scorex-VERSION-windows-x86_64.zip + ``` +3. Move the binary to a directory in your PATH: + ```bash + # macOS/Linux + sudo mv scorex-platform /usr/local/bin/scorex + sudo chmod +x /usr/local/bin/scorex -1. Create and push a new version tag: + # Windows - move to a directory in your PATH or add the directory to PATH + ``` +4. **macOS only**: Remove the quarantine attribute (required for unsigned binaries): ```bash - git tag v1.0.0 - git push origin v1.0.0 + sudo xattr -d com.apple.quarantine /usr/local/bin/scorex ``` + + Alternatively, on first run, right-click the binary in Finder and select "Open" to bypass Gatekeeper. -2. GitHub Actions will automatically: - - Build binaries for all platforms - - Create compressed archives - - Generate checksums - - Create a GitHub release +5. Verify installation: + ```bash + scorex version + ``` -3. Update package manifests: +**Note for macOS users**: The binaries are currently unsigned. You may see a security warning. Use the `xattr` command above or right-click > Open to bypass Gatekeeper. - **Homebrew Formula** (`distribution/homebrew/scorex.rb`): - - Update version number - - Update SHA256 checksums from `checksums.txt` in the release +### For Maintainers - **Scoop Manifest** (`distribution/scoop/scorex.json`): - - Update version number - - Update SHA256 hash from `checksums.txt` +#### Testing the Release Flow in PRs -4. Commit and push updated manifests to respective repositories: - - Homebrew: Create/update tap repository at `eclipse-score/homebrew-tap` - - Scoop: Create/update bucket repository at `eclipse-score/scoop-bucket` +The release workflow runs on PRs and creates artifacts. To test the binaries: -#### Setting Up Package Repositories +1. **Go to the PR's Actions tab** and find the latest "Release scorex CLI" workflow run +2. **Download the artifact** for your platform: + - `scorex-linux` - Contains Linux binary + - `scorex-macos` - Contains macOS binaries (ARM64 + Intel) + - `scorex-windows` - Contains Windows binary -**Homebrew Tap:** -1. Create repository: `https://github.com/eclipse-score/homebrew-tap` -2. Add `distribution/homebrew/scorex.rb` to the repository root or `Formula/` directory -3. Users can then install with: `brew install eclipse-score/tap/scorex` +3. **Extract and test locally**: + ```bash + # Download artifact from GitHub Actions UI + unzip scorex-macos.zip + + # Extract the tar.gz + tar -xzf scorex-pr-*-macos-arm64.tar.gz + + # Make executable and remove quarantine (macOS) + chmod +x scorex-macos-arm64 + xattr -d com.apple.quarantine scorex-macos-arm64 2>/dev/null || true + + # Test it + ./scorex-macos-arm64 --help + ./scorex-macos-arm64 version + + # Test creating a project + ./scorex-macos-arm64 init --name test_app --dir /tmp/test_scorex + ``` -**Scoop Bucket:** -1. Create repository: `https://github.com/eclipse-score/scoop-bucket` -2. Add `distribution/scoop/scorex.json` to the `bucket/` directory -3. Users can then install with: `scoop bucket add eclipse-score ` then `scoop install scorex` +**Note**: The install script cannot be tested in PRs since it requires a published GitHub release. -#### Updating Checksums +#### Publishing a New Release -After each release, download `checksums.txt` from the GitHub release and update: +1. **Create and push a version tag:** + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` -```bash -# Example for version 1.0.0 -curl -sL https://github.com/eclipse-score/score_scrample/releases/download/v1.0.0/checksums.txt +2. **GitHub Actions automatically:** + - Builds binaries for all platforms (Linux x86_64, macOS ARM64, macOS Intel, Windows x86_64) + - Creates compressed archives (.tar.gz for Unix, .zip for Windows) + - Generates `checksums.txt` with SHA256 hashes + - Creates a GitHub release with all artifacts + - For PRs and manual runs: Uploads separate artifacts per platform (`scorex-linux`, `scorex-macos`, `scorex-windows`) -# Update the SHA256 values in: -# - distribution/homebrew/scorex.rb -# - distribution/scoop/scorex.json -``` +3. **Users can install** via the install script or manual download from the releases page diff --git a/scorex/distribution/homebrew/scorex.rb b/scorex/distribution/homebrew/scorex.rb deleted file mode 100644 index 8cc6d54..0000000 --- a/scorex/distribution/homebrew/scorex.rb +++ /dev/null @@ -1,39 +0,0 @@ -class Scorex < Formula - desc "CLI for creating S-CORE skeleton projects" - homepage "https://github.com/eclipse-score/score_scrample" - version "0.1.0" - license "Apache-2.0" - - on_macos do - if Hardware::CPU.arm? - url "https://github.com/eclipse-score/score_scrample/releases/download/v#{version}/scorex-#{version}-macos-arm64.tar.gz" - sha256 "REPLACE_WITH_ACTUAL_SHA256_ARM64" - else - url "https://github.com/eclipse-score/score_scrample/releases/download/v#{version}/scorex-#{version}-macos-x86_64.tar.gz" - sha256 "REPLACE_WITH_ACTUAL_SHA256_X86_64" - end - end - - on_linux do - if Hardware::CPU.intel? - url "https://github.com/eclipse-score/score_scrample/releases/download/v#{version}/scorex-#{version}-linux-x86_64.tar.gz" - sha256 "REPLACE_WITH_ACTUAL_SHA256_LINUX" - end - end - - def install - if OS.mac? - if Hardware::CPU.arm? - bin.install "scorex-macos-arm64" => "scorex" - else - bin.install "scorex-macos-x86_64" => "scorex" - end - elsif OS.linux? - bin.install "scorex-linux-x86_64" => "scorex" - end - end - - test do - system "#{bin}/scorex", "version" - end -end diff --git a/scorex/distribution/install.sh b/scorex/distribution/install.sh index f941b60..28b1418 100755 --- a/scorex/distribution/install.sh +++ b/scorex/distribution/install.sh @@ -51,7 +51,18 @@ detect_platform() { get_latest_version() { VERSION=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') if [ -z "$VERSION" ]; then - echo "Error: Could not fetch latest version" + echo "" + echo "Error: No releases found for scorex" + echo "" + echo "To use this installer, a release must be published first." + echo "Maintainers: Create a release by pushing a version tag:" + echo " git tag v0.1.0" + echo " git push origin v0.1.0" + echo "" + echo "For now, you can build from source:" + echo " cd scorex" + echo " go build -o scorex ." + echo "" exit 1 fi echo "Latest version: $VERSION" @@ -86,6 +97,12 @@ install_scorex() { mv "$BINARY" "$INSTALL_DIR/scorex" chmod +x "$INSTALL_DIR/scorex" + # Remove quarantine attribute on macOS + if [ "$OS" = "Darwin" ]; then + echo "Removing macOS quarantine attribute..." + xattr -d com.apple.quarantine "$INSTALL_DIR/scorex" 2>/dev/null || true + fi + rm -rf "$TEMP_DIR" echo "" diff --git a/scorex/distribution/scoop/scorex.json b/scorex/distribution/scoop/scorex.json deleted file mode 100644 index d677207..0000000 --- a/scorex/distribution/scoop/scorex.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "0.1.0", - "description": "CLI for creating S-CORE skeleton projects", - "homepage": "https://github.com/eclipse-score/score_scrample", - "license": "Apache-2.0", - "architecture": { - "64bit": { - "url": "https://github.com/eclipse-score/score_scrample/releases/download/v0.1.0/scorex-0.1.0-windows-x86_64.zip", - "hash": "REPLACE_WITH_ACTUAL_SHA256", - "bin": "scorex-windows-x86_64.exe" - } - }, - "checkver": { - "github": "https://github.com/eclipse-score/score_scrample" - }, - "autoupdate": { - "architecture": { - "64bit": { - "url": "https://github.com/eclipse-score/score_scrample/releases/download/v$version/scorex-$version-windows-x86_64.zip" - } - } - } -}