Create Tag and Release #37
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: Create Tag and Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag (required, e.g. v0.2.0)" | |
| required: true | |
| type: string | |
| prerelease: | |
| description: "Mark as pre-release" | |
| required: false | |
| type: boolean | |
| default: false | |
| draft: | |
| description: "Create as draft" | |
| required: false | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ inputs.tag }} | |
| cancel-in-progress: false | |
| env: | |
| TAP_REPO: drpedapati/homebrew-tap | |
| FORMULA_RELATIVE_PATH: Formula/sciclaw.rb | |
| jobs: | |
| create-tag: | |
| name: Create Git Tag | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create and push tag | |
| shell: bash | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag -a "${{ inputs.tag }}" -m "Release ${{ inputs.tag }}" | |
| git push origin "${{ inputs.tag }}" | |
| build-binaries: | |
| name: Build Release Binaries | |
| needs: create-tag | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout tag | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ inputs.tag }} | |
| - name: Setup Go from go.mod | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| - name: Build all binaries | |
| run: make build-all | |
| - name: Generate checksums | |
| shell: bash | |
| run: | | |
| shasum -a 256 build/sciclaw-* build/picoclaw-* > build/sha256sums.txt | |
| - name: Upload release binaries artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sciclaw-binaries | |
| path: | | |
| build/sciclaw-* | |
| build/picoclaw-* | |
| build/sha256sums.txt | |
| if-no-files-found: error | |
| create-release: | |
| name: Create GitHub Release | |
| needs: [create-tag, build-binaries] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: release-artifacts | |
| - name: Show downloaded files | |
| run: ls -R release-artifacts | |
| - name: Create release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ inputs.tag }} | |
| name: ${{ inputs.tag }} | |
| draft: ${{ inputs.draft }} | |
| prerelease: ${{ inputs.prerelease }} | |
| files: | | |
| release-artifacts/**/* | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| update-homebrew-tap: | |
| name: Update Homebrew Tap Formula | |
| needs: [create-tag, build-binaries, create-release] | |
| if: ${{ !inputs.prerelease && !inputs.draft }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Check Homebrew tap token | |
| id: tap-token | |
| shell: bash | |
| env: | |
| HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| run: | | |
| if [ -z "${HOMEBREW_TAP_TOKEN}" ]; then | |
| echo "available=false" >> "${GITHUB_OUTPUT}" | |
| echo "HOMEBREW_TAP_TOKEN is not configured; skipping tap update." | |
| else | |
| echo "available=true" >> "${GITHUB_OUTPUT}" | |
| fi | |
| - name: Compute source archive checksum | |
| if: ${{ steps.tap-token.outputs.available == 'true' }} | |
| id: source | |
| shell: bash | |
| run: | | |
| tag="${{ inputs.tag }}" | |
| source_url="https://github.com/${{ github.repository }}/archive/refs/tags/${tag}.tar.gz" | |
| curl -fsSL -o source.tar.gz "${source_url}" | |
| source_sha256="$(shasum -a 256 source.tar.gz | awk '{print $1}')" | |
| echo "url=${source_url}" >> "${GITHUB_OUTPUT}" | |
| echo "sha256=${source_sha256}" >> "${GITHUB_OUTPUT}" | |
| echo "version=${tag#v}" >> "${GITHUB_OUTPUT}" | |
| - name: Checkout tap repository | |
| if: ${{ steps.tap-token.outputs.available == 'true' }} | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: ${{ env.TAP_REPO }} | |
| token: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| path: tap | |
| - name: Render formula | |
| if: ${{ steps.tap-token.outputs.available == 'true' }} | |
| shell: bash | |
| run: | | |
| source_url="${{ steps.source.outputs.url }}" | |
| source_sha256="${{ steps.source.outputs.sha256 }}" | |
| version="${{ steps.source.outputs.version }}" | |
| mkdir -p "tap/Formula" | |
| cat > "tap/${{ env.FORMULA_RELATIVE_PATH }}" <<EOF | |
| class Sciclaw < Formula | |
| desc "Autonomous paired scientist CLI forked from PicoClaw" | |
| homepage "https://github.com/drpedapati/sciclaw" | |
| url "${source_url}" | |
| sha256 "${source_sha256}" | |
| license "MIT" | |
| depends_on "go" => :build | |
| on_linux do | |
| depends_on "sciclaw-quarto" | |
| end | |
| depends_on "irl" | |
| depends_on "ripgrep" | |
| depends_on "sciclaw-docx-review" | |
| depends_on "sciclaw-pubmed-cli" | |
| def install | |
| ENV["CGO_ENABLED"] = "0" | |
| ldflags = "-s -w -X main.version=#{version}" | |
| system "go", "build", *std_go_args(output: bin/"sciclaw", ldflags: ldflags), "./cmd/picoclaw" | |
| (bin/"picoclaw").make_symlink bin/"sciclaw" | |
| pkgshare.install "skills" | |
| (pkgshare/"templates"/"workspace").install Dir["pkg/workspacetpl/templates/workspace/*.md"] | |
| end | |
| test do | |
| assert_match "Usage:", shell_output("#{bin}/sciclaw 2>&1", 1) | |
| assert_match "Usage:", shell_output("#{bin}/picoclaw 2>&1", 1) | |
| assert_match "v#{version}", shell_output("#{bin}/sciclaw --version") | |
| assert_match "ripgrep", shell_output("#{Formula["ripgrep"].opt_bin}/rg --version") | |
| assert_match "irl", shell_output("#{Formula["irl"].opt_bin}/irl --version 2>&1") | |
| if OS.linux? | |
| assert_match(/\\d+\\.\\d+\\.\\d+/, shell_output("#{Formula["sciclaw-quarto"].opt_bin}/quarto --version").strip) | |
| end | |
| assert_match "docx-review", shell_output("#{Formula["sciclaw-docx-review"].opt_bin}/docx-review --version") | |
| assert_match "PubMed", shell_output("#{Formula["sciclaw-pubmed-cli"].opt_bin}/pubmed --help") | |
| ENV["HOME"] = testpath | |
| system bin/"sciclaw", "onboard", "--yes" | |
| assert_path_exists testpath/"sciclaw/AGENTS.md" | |
| assert_path_exists testpath/"sciclaw/HOOKS.md" | |
| assert_path_exists testpath/"sciclaw/skills/scientific-writing/SKILL.md" | |
| end | |
| end | |
| EOF | |
| - name: Commit and push formula update | |
| if: ${{ steps.tap-token.outputs.available == 'true' }} | |
| shell: bash | |
| run: | | |
| cd tap | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| if git diff --quiet -- "${{ env.FORMULA_RELATIVE_PATH }}"; then | |
| echo "No tap formula changes detected." | |
| exit 0 | |
| fi | |
| git add "${{ env.FORMULA_RELATIVE_PATH }}" | |
| git commit -m "sciclaw ${{ inputs.tag }}" | |
| git push origin main |