fix(M-025.1): suppress Untitled-1 tab when launched with pending opens #34
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
| # Phase-B4 step-1 release workflow. | |
| # | |
| # Triggered by git tag push matching v*.* — produces signed, smoke- | |
| # tested DMG artifacts and publishes them as a GitHub Release with | |
| # .sha256 sidecars. The Homebrew cask formula sources sha256 from | |
| # the sidecar (NOT recomputed) per B2CR-3. | |
| # | |
| # Replaces the Phase-B1.5 dryrun workflow (release-tauri.yml) which | |
| # was triggered by branch pushes. release-tauri.yml is retained as a | |
| # named-environment dryrun for branch-time validation. | |
| # | |
| # Phase-B4 prerequisites still in flight: ed25519 signer keypair for | |
| # tauri-plugin-updater (F-UPDATER-WIRE-PLUGIN), SLSA-3 provenance via | |
| # actions/attest-build-provenance + Sigstore Fulcio (B4 step-11/12), | |
| # cross-repo cask PR via xronocode-release-bot GitHub App (B4 step-15). | |
| # Each lands in its own follow-up PR; this workflow ships the build + | |
| # release skeleton that they wire into. | |
| name: release | |
| on: | |
| push: | |
| tags: | |
| - 'v*.*.*' | |
| - 'v*.*.*-*' | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Tag name to release (e.g. v2.0.0). Leave empty for current ref.' | |
| required: false | |
| default: '' | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write # gh release create needs write | |
| id-token: write # B4 step-11 SLSA + Sigstore OIDC (wired in follow-up PR) | |
| attestations: write # B4 step-11 actions/attest-build-provenance (follow-up) | |
| jobs: | |
| build: | |
| name: build (${{ matrix.platform.name }}) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| platform: | |
| - name: macos-arm64 | |
| os: macos-14 | |
| target: aarch64-apple-darwin | |
| runs-on: ${{ matrix.platform.os }} | |
| timeout-minutes: 60 | |
| outputs: | |
| tag: ${{ steps.resolve_tag.outputs.tag }} | |
| steps: | |
| # ── checkout + tooling ──────────────────────────────────────── | |
| - name: checkout | |
| uses: actions/checkout@v4 | |
| - name: resolve tag | |
| id: resolve_tag | |
| run: | | |
| if [ -n "${{ inputs.tag }}" ]; then | |
| TAG="${{ inputs.tag }}" | |
| else | |
| TAG="${GITHUB_REF#refs/tags/}" | |
| fi | |
| if [ -z "$TAG" ] || [ "$TAG" = "$GITHUB_REF" ]; then | |
| echo "::error::could not resolve tag from ref=$GITHUB_REF inputs.tag='${{ inputs.tag }}'" | |
| exit 1 | |
| fi | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "resolved tag: $TAG" | |
| - name: setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: npm | |
| - name: setup rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.platform.target }} | |
| - name: cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| src-tauri/target | |
| key: cargo-${{ matrix.platform.target }}-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| cargo-${{ matrix.platform.target }}- | |
| # ── install + build frontend ───────────────────────────────── | |
| - name: npm ci | |
| run: npm ci | |
| - name: vite build | |
| run: npm run build | |
| # ── tauri build (with updater signing) ─────────────────────── | |
| # F-UPDATER-WIRE-PLUGIN: TAURI_SIGNING_PRIVATE_KEY env feeds | |
| # tauri-action's auto-sign. _PASSWORD is optional — if the | |
| # keypair was generated with empty password, GH resolves the | |
| # missing secret to "" and tauri-action treats it as no-password. | |
| # | |
| # tauri-action emits Mark.app + DMG + Mark.app.tar.gz + | |
| # Mark.app.tar.gz.sig (ed25519 signature). The .sig is what | |
| # the updater plugin verifies against plugins.updater.pubkey | |
| # before applying an update on user machines. | |
| # | |
| # If TAURI_SIGNING_PRIVATE_KEY itself is missing (first runs | |
| # before user provisions the keypair), tauri-action falls | |
| # through to unsigned build — users on those builds won't have | |
| # working in-app updates, but `brew upgrade --cask mark` still | |
| # works. | |
| - name: tauri build | |
| id: tauri | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| with: | |
| args: --target ${{ matrix.platform.target }} | |
| # ── ad-hoc signing ─────────────────────────────────────────── | |
| - name: ad-hoc codesign | |
| if: matrix.platform.os == 'macos-14' | |
| run: | | |
| set -euo pipefail | |
| APP_PATH=$(find target -name 'Mark.app' -type d | head -1) | |
| if [ -z "$APP_PATH" ]; then | |
| echo "::error::Mark.app not found under target" | |
| exit 1 | |
| fi | |
| echo "signing: $APP_PATH" | |
| codesign --force --deep --sign - "$APP_PATH" | |
| codesign --verify --verbose=4 "$APP_PATH" | |
| # ── smoke launch ───────────────────────────────────────────── | |
| - name: smoke launch | |
| if: matrix.platform.os == 'macos-14' | |
| run: | | |
| set -euo pipefail | |
| DMG=$(find target -name '*.dmg' | head -1) | |
| if [ -z "$DMG" ]; then | |
| echo "::error::no .dmg artifact produced" | |
| exit 1 | |
| fi | |
| MOUNT=/tmp/mark-dmg | |
| mkdir -p "$MOUNT" | |
| hdiutil attach "$DMG" -nobrowse -mountpoint "$MOUNT" -readonly | |
| cp -R "$MOUNT/Mark.app" /Applications/ | |
| hdiutil detach "$MOUNT" | |
| xattr -cr /Applications/Mark.app | |
| MARK_SKIP_MIGRATION=1 open -a /Applications/Mark.app | |
| for i in $(seq 1 10); do | |
| if pgrep -f 'Mark.app/Contents/MacOS/mark' > /dev/null; then | |
| echo "alive after ${i}s" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| if ! pgrep -f 'Mark.app/Contents/MacOS/mark' > /dev/null; then | |
| echo "::error::Mark process did not appear within 10s of open" | |
| exit 1 | |
| fi | |
| pkill -9 -f 'Mark.app/Contents/MacOS/mark' || true | |
| # ── bundle size budget ─────────────────────────────────────── | |
| - name: bundle size | |
| if: matrix.platform.os == 'macos-14' | |
| id: size | |
| run: | | |
| set -euo pipefail | |
| APP_PATH=/Applications/Mark.app | |
| if [ ! -d "$APP_PATH" ]; then | |
| APP_PATH=$(find target -name 'Mark.app' -type d | head -1) | |
| fi | |
| BYTES=$(du -sk "$APP_PATH" | awk '{print $1*1024}') | |
| HUMAN=$(du -sh "$APP_PATH" | awk '{print $1}') | |
| echo "bundle_bytes=$BYTES" >> "$GITHUB_OUTPUT" | |
| echo "bundle_human=$HUMAN" >> "$GITHUB_OUTPUT" | |
| { | |
| echo "## Bundle size — ${{ matrix.platform.name }}" | |
| echo | |
| echo "- \`du -sh\`: **$HUMAN**" | |
| echo "- bytes: $BYTES" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| # ── warnings allowlist ─────────────────────────────────────── | |
| - name: warnings allowlist check | |
| if: matrix.platform.os == 'macos-14' | |
| run: | | |
| set -uo pipefail # NOT -e so we can show JSON before failing | |
| cd src-tauri | |
| # Force re-emit of warnings: cargo's incremental cache | |
| # otherwise hides warnings from already-compiled crates. | |
| touch src/main.rs | |
| cargo build --release --bin mark --message-format=json > /tmp/cargo.json | |
| cd .. | |
| node tools/check-warnings-allowlist.mjs /tmp/cargo.json docs/ci-warnings-allowlist.md \ | |
| | tee /tmp/toolchain-warnings.json | |
| RC=${PIPESTATUS[0]} | |
| echo "---" | |
| echo "verifier exit code: $RC" | |
| exit $RC | |
| # ── attribution-completeness gate (B4 step-9) ──────────────── | |
| # Re-runs license-checker + cargo-bundle-licenses, diffs against | |
| # committed NOTICES-{node,rust}.md. New deps without an attribution | |
| # line fail the build. | |
| - name: install cargo-bundle-licenses | |
| if: matrix.platform.os == 'macos-14' | |
| run: cargo install cargo-bundle-licenses | |
| - name: verify attributions | |
| if: matrix.platform.os == 'macos-14' | |
| run: ./tools/verify-attributions.sh | |
| # ── SBOM generation (B4 step-9) ────────────────────────────── | |
| # CycloneDX SPDX-compatible SBOM for the Tauri binary + Node | |
| # renderer dependency closure. Published alongside the DMG so | |
| # downstream auditors can verify the supply chain. | |
| - name: install cargo-cyclonedx | |
| if: matrix.platform.os == 'macos-14' | |
| run: cargo install cargo-cyclonedx | |
| - name: generate SBOM | |
| if: matrix.platform.os == 'macos-14' | |
| run: | | |
| set -euo pipefail | |
| mkdir -p sbom | |
| # Node side: production deps only | |
| npx --yes --package @cyclonedx/cyclonedx-npm -- cyclonedx-npm \ | |
| --output-format JSON \ | |
| --output-file sbom/sbom-node.cdx.json \ | |
| --omit dev \ | |
| --ignore-npm-errors | |
| # Rust side — cargo-cyclonedx 0.5.x writes <crate>.cdx.json | |
| # to the manifest directory; we relocate to sbom/. | |
| (cd src-tauri && cargo cyclonedx --format json) | |
| mv src-tauri/mark.cdx.json sbom/sbom-rust.cdx.json | |
| ls -la sbom/ | |
| # ── updater latest.json feed (B4 step-5) ───────────────────── | |
| # tauri-plugin-updater fetches this file from the URL configured | |
| # in tauri.conf.json plugins.updater.endpoints[]. It contains the | |
| # ed25519 signature of the .app.tar.gz updater bundle that | |
| # tauri-action produced; the plugin verifies before downloading. | |
| # If signing keys aren't provisioned, the .sig file is missing | |
| # and we skip the feed (graceful degradation). | |
| - name: build updater feed (latest.json) | |
| if: matrix.platform.os == 'macos-14' | |
| id: feed | |
| run: | | |
| set -euo pipefail | |
| TAG=${{ steps.resolve_tag.outputs.tag }} | |
| VER="${TAG#v}" | |
| SIG_FILE=$(find target -name '*.app.tar.gz.sig' | head -1) | |
| TGZ_FILE=$(find target -name '*.app.tar.gz' ! -name '*.sig' | head -1) | |
| if [ -z "$SIG_FILE" ] || [ -z "$TGZ_FILE" ]; then | |
| echo "::warning::updater signing artifacts missing; latest.json not generated. Configure TAURI_SIGNING_PRIVATE_KEY+_PASSWORD secrets per docs/F-UPDATER-WIRE-PLUGIN-handoff.md." | |
| echo "skipped=1" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| SIG=$(cat "$SIG_FILE") | |
| PUB_DATE=$(date -u '+%Y-%m-%dT%H:%M:%SZ') | |
| mkdir -p /tmp/release | |
| # Copy the .app.tar.gz so it gets uploaded as a release asset. | |
| cp "$TGZ_FILE" "/tmp/release/Mark_${VER}_aarch64.app.tar.gz" | |
| cat > /tmp/release/latest.json <<JSON | |
| { | |
| "version": "${TAG}", | |
| "notes": "See release notes at https://github.com/xronocode/mark/releases/tag/${TAG}", | |
| "pub_date": "${PUB_DATE}", | |
| "platforms": { | |
| "darwin-aarch64": { | |
| "signature": "${SIG}", | |
| "url": "https://github.com/xronocode/mark/releases/download/${TAG}/Mark_${VER}_aarch64.app.tar.gz" | |
| } | |
| } | |
| } | |
| JSON | |
| echo "skipped=0" >> "$GITHUB_OUTPUT" | |
| cat /tmp/release/latest.json | |
| # ── stage release artifacts ────────────────────────────────── | |
| # Per B2CR-3: the cask sources sha256 from a .sha256 sidecar that | |
| # ships with the DMG, NOT a recomputed value. CI emits the sidecar | |
| # so the cask formula and the release artifact agree. | |
| - name: stage release artifacts | |
| if: matrix.platform.os == 'macos-14' | |
| id: stage | |
| run: | | |
| set -euo pipefail | |
| mkdir -p /tmp/release | |
| DMG_SRC=$(find target -name '*.dmg' | head -1) | |
| if [ -z "$DMG_SRC" ]; then | |
| echo "::error::no .dmg artifact produced" | |
| exit 1 | |
| fi | |
| TAG=${{ steps.resolve_tag.outputs.tag }} | |
| # Strip leading 'v' from tag for filename version segment | |
| # (matches v1 cask convention: Mark_1.2.3_aarch64.dmg). | |
| VER=${TAG#v} | |
| DMG_DST=/tmp/release/Mark_${VER}_aarch64.dmg | |
| cp "$DMG_SRC" "$DMG_DST" | |
| shasum -a 256 "$DMG_DST" | awk '{print $1}' > "$DMG_DST.sha256" | |
| # B4-step-8 attribution + B4-step-9 SBOM artifacts shipped | |
| # alongside the DMG so downstream cask + audit consumers | |
| # don't need to re-clone the repo. | |
| cp NOTICES-node.md /tmp/release/ | |
| cp NOTICES-rust.md /tmp/release/ | |
| cp sbom/sbom-node.cdx.json /tmp/release/Mark_${VER}_sbom-node.cdx.json | |
| cp sbom/sbom-rust.cdx.json /tmp/release/Mark_${VER}_sbom-rust.cdx.json | |
| ls -la /tmp/release | |
| echo "dmg=$DMG_DST" >> "$GITHUB_OUTPUT" | |
| echo "sha256=$DMG_DST.sha256" >> "$GITHUB_OUTPUT" | |
| # ── upload as workflow artifact for downstream jobs ────────── | |
| # ── SLSA-3 build provenance (B4 step-11) ───────────────────── | |
| # actions/attest-build-provenance@v2 issues a Sigstore-anchored | |
| # in-toto attestation that proves the artifact was built by THIS | |
| # workflow run on THIS commit. OIDC → Fulcio → ephemeral cert → | |
| # signed bundle published to the GH Releases page alongside the | |
| # DMG. Verification command goes in release notes: | |
| # gh attestation verify Mark_v2.0.0_aarch64.dmg --owner xronocode | |
| - name: SLSA build provenance | |
| if: matrix.platform.os == 'macos-14' | |
| uses: actions/attest-build-provenance@v2 | |
| with: | |
| subject-path: '/tmp/release/Mark_*.dmg' | |
| # ── Cosign keyless sign-blob (B4 step-12) ──────────────────── | |
| # Belt-and-braces over the SLSA attestation: a keyless cosign | |
| # signature using the same OIDC → Fulcio path. Produces a | |
| # .bundle file users can verify with: | |
| # cosign verify-blob \ | |
| # --bundle Mark_v2.0.0_aarch64.dmg.bundle \ | |
| # --certificate-identity-regexp 'https://github\.com/xronocode/mark/.*' \ | |
| # --certificate-oidc-issuer https://token.actions.githubusercontent.com \ | |
| # Mark_v2.0.0_aarch64.dmg | |
| - name: install cosign | |
| if: matrix.platform.os == 'macos-14' | |
| uses: sigstore/cosign-installer@v3 | |
| with: | |
| cosign-release: 'v2.4.1' | |
| - name: cosign sign-blob | |
| if: matrix.platform.os == 'macos-14' | |
| env: | |
| COSIGN_EXPERIMENTAL: '1' | |
| run: | | |
| set -euo pipefail | |
| for DMG in /tmp/release/Mark_*.dmg; do | |
| cosign sign-blob --yes --bundle "$DMG.bundle" "$DMG" | |
| ls -la "$DMG.bundle" | |
| done | |
| - name: upload release artifacts | |
| if: matrix.platform.os == 'macos-14' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mark-${{ matrix.platform.name }}-release | |
| path: | | |
| /tmp/release/*.dmg | |
| /tmp/release/*.sha256 | |
| /tmp/release/*.bundle | |
| /tmp/release/Mark_*_sbom-*.cdx.json | |
| /tmp/release/NOTICES-*.md | |
| /tmp/release/Mark_*.app.tar.gz | |
| /tmp/release/latest.json | |
| if-no-files-found: error | |
| retention-days: 30 | |
| publish: | |
| name: publish github release | |
| needs: build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: checkout | |
| uses: actions/checkout@v4 | |
| - name: download release artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/release-stage | |
| - name: list staged | |
| run: | | |
| find /tmp/release-stage -type f -exec ls -la {} \; | |
| # ── create GitHub release + upload assets ──────────────────── | |
| # B4 step-15 will replace this with cross-repo cask PR via the | |
| # xronocode-release-bot GitHub App + environment-protection | |
| # `release` requiring manual approval. For now, ambient | |
| # GITHUB_TOKEN with contents:write permission ships the build | |
| # to the project's own Releases page. | |
| - name: gh release create | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| TAG=${{ needs.build.outputs.tag }} | |
| VER="${TAG#v}" | |
| FILES=$(find /tmp/release-stage -type f) | |
| NOTES=$(cat <<NOTES_EOF | |
| Automated release from \`$GITHUB_SHA\`. | |
| **Verification:** | |
| Build provenance (SLSA-3): | |
| \`\`\` | |
| gh attestation verify Mark_${VER}_aarch64.dmg --owner xronocode | |
| \`\`\` | |
| Cosign keyless signature: | |
| \`\`\` | |
| cosign verify-blob \\ | |
| --bundle Mark_${VER}_aarch64.dmg.bundle \\ | |
| --certificate-identity-regexp 'https://github.com/xronocode/mark/.*' \\ | |
| --certificate-oidc-issuer https://token.actions.githubusercontent.com \\ | |
| Mark_${VER}_aarch64.dmg | |
| \`\`\` | |
| DMG SHA-256 sidecar published as \`Mark_${VER}_aarch64.dmg.sha256\`. | |
| CycloneDX SBOMs published for both Node renderer and Rust backend | |
| dependency closures. NOTICES-{node,rust}.md attribution lists | |
| shipped alongside. | |
| **Updater:** ed25519-signed feed (\`latest.json\` + \`Mark_${VER}_aarch64.app.tar.gz\`) shipped. | |
| tauri-plugin-updater verifies against the embedded pubkey before applying. To upgrade | |
| outside the in-app updater: | |
| \`\`\` | |
| brew upgrade --cask mark | |
| \`\`\` | |
| NOTES_EOF | |
| ) | |
| if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | |
| echo "release $TAG already exists; uploading assets idempotently" | |
| gh release upload "$TAG" $FILES --repo "$GITHUB_REPOSITORY" --clobber | |
| else | |
| gh release create "$TAG" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "Mark $TAG" \ | |
| --notes "$NOTES" \ | |
| $FILES | |
| fi | |
| publish-cask: | |
| name: cross-repo cask PR | |
| needs: [build, publish] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| environment: release # gates on environment-protection approval | |
| # B4 step-15: cross-repo PR via xronocode-release-bot GitHub App. | |
| # The App's installation token has contents:write on | |
| # xronocode/homebrew-mark and pull-requests:write to open the bump | |
| # PR. Falls through with a noisy warning if APP_ID/PRIVATE_KEY | |
| # secrets are missing — this lets the rest of the release ship | |
| # while the App is being provisioned. | |
| steps: | |
| - name: checkout reborn-mark | |
| uses: actions/checkout@v4 | |
| - name: download release artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/release-stage | |
| - name: gate on App secrets | |
| id: gate | |
| run: | | |
| if [ -z "${{ secrets.RELEASE_BOT_APP_ID }}" ] || [ -z "${{ secrets.RELEASE_BOT_PRIVATE_KEY }}" ]; then | |
| echo "::warning::xronocode-release-bot App secrets not configured; skipping cask PR. See docs/F-CASK-PUBLISH-HANDOFF.md." | |
| echo "skip=1" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "skip=0" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: mint app installation token | |
| if: steps.gate.outputs.skip == '0' | |
| id: app_token | |
| uses: actions/create-github-app-token@v2 | |
| with: | |
| app-id: ${{ secrets.RELEASE_BOT_APP_ID }} | |
| private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }} | |
| owner: xronocode | |
| repositories: homebrew-mark | |
| - name: open cask bump PR | |
| if: steps.gate.outputs.skip == '0' | |
| env: | |
| GH_TOKEN: ${{ steps.app_token.outputs.token }} | |
| TAG: ${{ needs.build.outputs.tag }} | |
| run: | | |
| set -euo pipefail | |
| VER="${TAG#v}" | |
| # Pull the .sha256 sidecar value (NOT recompute) per B2CR-3. | |
| SHA256_FILE=$(find /tmp/release-stage -name "Mark_${VER}_aarch64.dmg.sha256" | head -1) | |
| if [ -z "$SHA256_FILE" ]; then | |
| echo "::error::sha256 sidecar missing for $TAG" | |
| exit 1 | |
| fi | |
| SHA256=$(awk '{print $1}' < "$SHA256_FILE") | |
| # Configure git to use the GH App token via gh's credential | |
| # helper. Without this, `git push` falls through to the default | |
| # askpass and fails: "could not read Username for github.com". | |
| gh auth setup-git | |
| # Clone tap, bump, push, open PR. | |
| gh repo clone xronocode/homebrew-mark /tmp/tap -- --depth 1 | |
| cd /tmp/tap | |
| git config user.name 'xronocode-release-bot[bot]' | |
| git config user.email 'xronocode-release-bot[bot]@users.noreply.github.com' | |
| BRANCH="bump/mark-${VER}" | |
| git checkout -b "$BRANCH" | |
| # Update version + sha256. Cask uses on_arm sha256 + url. | |
| sed -i'' -e "s|version \".*\"|version \"$VER\"|" Casks/mark.rb | |
| # Replace the on_arm sha256 line. | |
| awk -v sha="$SHA256" ' | |
| BEGIN { in_arm=0 } | |
| /^ on_arm do/ { in_arm=1 } | |
| in_arm && /sha256 / { sub(/sha256 \"[a-f0-9]+\"/, "sha256 \"" sha "\""); in_arm=0 } | |
| { print } | |
| ' Casks/mark.rb > Casks/mark.rb.tmp && mv Casks/mark.rb.tmp Casks/mark.rb | |
| git add Casks/mark.rb | |
| git commit -m "Bump mark to ${VER}" | |
| git push origin "$BRANCH" | |
| gh pr create \ | |
| --repo xronocode/homebrew-mark \ | |
| --title "Bump mark to ${VER}" \ | |
| --body "Auto-generated by release.yml on tag ${TAG}. | |
| - DMG sha256 sourced verbatim from Mark_${VER}_aarch64.dmg.sha256 sidecar. | |
| - SLSA-3 attestation + Cosign bundle published with the release. | |
| - Smoke launch + warnings allowlist passed in CI. | |
| Verification before merge: \`brew install --cask --no-quarantine ./Casks/mark.rb\`" \ | |
| --base main \ | |
| --head "$BRANCH" |