feat(core): cli-3.23.1 — Loom M0: extract straymark-core (workspace +… #62
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 CLI | |
| on: | |
| push: | |
| tags: | |
| - 'cli-*' | |
| # Allow manual trigger (useful for re-runs or when tag already exists) | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Release tag (e.g., cli-3.2.0)' | |
| required: true | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # Determine the tag and version to build | |
| resolve-version: | |
| name: Resolve version | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: ${{ steps.resolve.outputs.tag }} | |
| version: ${{ steps.resolve.outputs.version }} | |
| steps: | |
| - name: Resolve tag and version | |
| id: resolve | |
| shell: bash | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG="${{ github.event.inputs.tag }}" | |
| else | |
| TAG="${{ github.ref_name }}" | |
| fi | |
| if [[ "$TAG" != cli-* ]]; then | |
| echo "ERROR: tag '$TAG' is not a CLI release (must start with cli-)" | |
| exit 1 | |
| fi | |
| VERSION="${TAG#cli-}" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "Building CLI $VERSION from tag $TAG" | |
| build-cli: | |
| name: Build CLI (${{ matrix.target }}) | |
| needs: [resolve-version] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| archive: tar.gz | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| archive: tar.gz | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| archive: tar.gz | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| archive: zip | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.resolve-version.outputs.tag }} | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install OpenSSL (Linux) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config | |
| - name: Verify Cargo.toml version matches tag | |
| shell: bash | |
| run: | | |
| CARGO_VERSION=$(grep '^version' cli/Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') | |
| TAG_VERSION="${{ needs.resolve-version.outputs.version }}" | |
| if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then | |
| echo "ERROR: Cargo.toml version ($CARGO_VERSION) does not match tag version ($TAG_VERSION)" | |
| exit 1 | |
| fi | |
| - name: Build release binary | |
| run: cargo build --release --manifest-path cli/Cargo.toml --target ${{ matrix.target }} | |
| - name: Package (Unix) | |
| if: matrix.archive == 'tar.gz' | |
| shell: bash | |
| run: | | |
| # Workspace root target/ since Loom M0 (cli/ is a workspace member) | |
| BINARY=target/${{ matrix.target }}/release/straymark | |
| ARCHIVE=straymark-cli-v${{ needs.resolve-version.outputs.version }}-${{ matrix.target }}.tar.gz | |
| tar czf "$ARCHIVE" -C "$(dirname "$BINARY")" "$(basename "$BINARY")" | |
| echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV" | |
| - name: Package (Windows) | |
| if: matrix.archive == 'zip' | |
| shell: bash | |
| run: | | |
| # Workspace root target/ since Loom M0 (cli/ is a workspace member) | |
| BINARY=target/${{ matrix.target }}/release/straymark.exe | |
| ARCHIVE=straymark-cli-v${{ needs.resolve-version.outputs.version }}-${{ matrix.target }}.zip | |
| cp "$BINARY" straymark.exe | |
| 7z a "$ARCHIVE" straymark.exe | |
| echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV" | |
| - name: Upload binary artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: cli-${{ matrix.target }} | |
| path: ${{ env.ARCHIVE }} | |
| upload-to-release: | |
| name: Upload binaries to release | |
| needs: [resolve-version, build-cli] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: release-artifacts | |
| - name: Collect release files | |
| run: | | |
| mkdir -p release | |
| find release-artifacts -type f \( -name "*.zip" -o -name "*.tar.gz" \) -exec cp {} release/ \; | |
| ls -la release/ | |
| - name: Create or update GitHub Release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| TAG="${{ needs.resolve-version.outputs.tag }}" | |
| VERSION="${{ needs.resolve-version.outputs.version }}" | |
| if gh release view "$TAG" > /dev/null 2>&1; then | |
| echo "Release $TAG exists, uploading binaries..." | |
| gh release upload "$TAG" release/* --clobber | |
| else | |
| echo "Creating release $TAG..." | |
| gh release create "$TAG" \ | |
| --title "StrayMark CLI $VERSION" \ | |
| --generate-notes \ | |
| --latest \ | |
| release/* | |
| fi | |
| - name: Delete previous CLI releases | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| CURRENT_TAG="${{ needs.resolve-version.outputs.tag }}" | |
| gh release list --json tagName --jq '.[].tagName' | while read -r tag; do | |
| if [[ "$tag" == cli-* && "$tag" != "$CURRENT_TAG" ]]; then | |
| echo "Deleting old release $tag..." | |
| gh release delete "$tag" --yes --cleanup-tag | |
| fi | |
| done | |
| publish-crate: | |
| name: Publish to crates.io | |
| needs: [resolve-version, upload-to-release] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.resolve-version.outputs.tag }} | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Publish straymark-core (if version not yet on crates.io) | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} | |
| shell: bash | |
| run: | | |
| # straymark-cli depends on straymark-core by version; the core crate | |
| # must exist on crates.io before the CLI can be published. | |
| CORE_VERSION=$(grep '^version' core/Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') | |
| if curl -fsSL "https://crates.io/api/v1/crates/straymark-core/$CORE_VERSION" | grep -q '"num"'; then | |
| echo "straymark-core $CORE_VERSION already published — skipping" | |
| else | |
| cargo publish --manifest-path core/Cargo.toml --allow-dirty | |
| fi | |
| - name: Publish straymark-cli to crates.io | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} | |
| run: cargo publish --manifest-path cli/Cargo.toml --allow-dirty |