Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/scripts/update-homebrew/commit-push.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Commit the updated formula as the fin-releases bot and push to homebrew-tap.
# Idempotent: exits 0 if the formula already matches.
#
# Required env: APP_SLUG, TOKEN, VERSION
# Assumes homebrew-tap has been checked out at ./homebrew-tap with TOKEN
# already configured as the remote credential.
set -euo pipefail

BOT_NAME="${APP_SLUG}[bot]"
BOT_ID=$(GH_TOKEN="$TOKEN" gh api "/users/${BOT_NAME}" --jq .id)

cd homebrew-tap
git config user.name "$BOT_NAME"
git config user.email "${BOT_ID}+${BOT_NAME}@users.noreply.github.com"

git add Formula/fintoc.rb
if git diff --cached --quiet; then
echo "Formula already up to date"
exit 0
fi

git commit -m "fintoc $VERSION" -m "https://github.com/fintoc-com/fintoc-cli/releases/tag/v$VERSION"
git push
21 changes: 21 additions & 0 deletions .github/scripts/update-homebrew/download-tarball.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Download the published tarball of @fintoc/cli@$VERSION and compute its
# SHA256. Writes `url` and `sha256` to $GITHUB_OUTPUT for downstream steps
# (the Homebrew formula needs both).
#
# Required env: VERSION, GITHUB_OUTPUT
set -euo pipefail

URL="https://registry.npmjs.org/@fintoc/cli/-/cli-${VERSION}.tgz"
TARBALL=$(mktemp)

HTTP_CODE=$(curl -sL -o "$TARBALL" -w '%{http_code}' "$URL")
if [ "$HTTP_CODE" != "200" ]; then
echo "Failed to download tarball (HTTP $HTTP_CODE)"
exit 1
fi

SHA256=$(sha256sum "$TARBALL" | awk '{print $1}')
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
echo "url=$URL" >> "$GITHUB_OUTPUT"
echo "Tarball downloaded: $URL (sha256=$SHA256)"
21 changes: 21 additions & 0 deletions .github/scripts/update-homebrew/resolve-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Resolve and validate the version to sync into the Homebrew formula.
# Strips a leading "v" and refuses anything not matching x.y.z.
#
# Required env: RAW_VERSION (may be empty if neither workflow_dispatch input
# nor release event provided one), GITHUB_OUTPUT
set -euo pipefail

if [ -z "${RAW_VERSION:-}" ]; then
echo "::error::No version provided and no release tag in event"
exit 1
fi

VERSION="${RAW_VERSION#v}"
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::Invalid version: $VERSION"
exit 1
fi

echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Resolved version: $VERSION"
32 changes: 32 additions & 0 deletions .github/scripts/update-homebrew/update-formula.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Required env: TARBALL_URL, TARBALL_SHA256, VERSION
# Assumes homebrew-tap has been checked out at ./homebrew-tap.
set -euo pipefail

for var in TARBALL_URL TARBALL_SHA256 VERSION; do
[ -z "${!var}" ] && echo "::error::$var is empty" && exit 1
done

envsubst '$TARBALL_URL $TARBALL_SHA256 $VERSION' > homebrew-tap/Formula/fintoc.rb <<'RUBY'
class Fintoc < Formula
desc "CLI for the Fintoc API"
homepage "https://github.com/fintoc-com/fintoc-cli"
url "$TARBALL_URL"
version "$VERSION"
sha256 "$TARBALL_SHA256"
license "BSD-3-Clause"

depends_on "node"

def install
system "npm", "install", *std_npm_args
bin.install_symlink Dir["#{libexec}/bin/*"]
end

test do
assert_match "fintoc/#{version}", shell_output("#{bin}/fintoc --version")
end
end
RUBY

echo "Formula written for version $VERSION"
20 changes: 20 additions & 0 deletions .github/scripts/update-homebrew/wait-npm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Poll the npm registry until @fintoc/cli@$VERSION shows up.
# Required env: VERSION
set -euo pipefail

MAX_ATTEMPTS=30
SLEEP_SECONDS=10

for i in $(seq 1 "$MAX_ATTEMPTS"); do
if npm view "@fintoc/cli@$VERSION" version 2>/dev/null; then
echo "Found @fintoc/cli@$VERSION on npm"
exit 0
fi
echo "Attempt $i/$MAX_ATTEMPTS - waiting ${SLEEP_SECONDS}s..."
sleep "$SLEEP_SECONDS"
done

echo "Timed out waiting for @fintoc/cli@$VERSION on npm"
npm view "@fintoc/cli" versions --json || true
exit 1
169 changes: 30 additions & 139 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,166 +1,57 @@
name: Release

on:
pull_request:
types: [closed]
branches: [main]

permissions:
contents: read
workflow_dispatch:
inputs:
bump:
description: 'Tipo de bump'
type: choice
required: true
default: minor
options: [patch, minor, major]
release-notes:
description: 'Release notes (markdown, opcional)'
type: string
required: false

jobs:
checks:
if: github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'release/')
release:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
tag_name: ${{ steps.version.outputs.tag_name }}
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: https://registry.npmjs.org
cache: npm

- name: Get version
id: version
run: |
VERSION=$(node -p 'require("./package.json").version')
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::Invalid version: $VERSION"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag_name=v$VERSION" >> "$GITHUB_OUTPUT"

- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm run build
- run: npm test

publish:
needs: checks
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
- uses: fintoc-com/release-action/prepare@main
id: prep
with:
node-version: 22
registry-url: https://registry.npmjs.org
cache: npm
bump: ${{ inputs.bump }}
version-format: npm
tag-prefix: v
app-id: ${{ vars.FIN_RELEASES_APP_ID }}
app-private-key: ${{ secrets.FIN_RELEASES_PRIVATE_KEY }}

- run: npm ci
- run: npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

update-homebrew:
needs: [checks, publish]
runs-on: ubuntu-latest
steps:
- name: Wait for npm publish
run: |
VERSION="${{ needs.checks.outputs.version }}"
for i in $(seq 1 30); do
if npm view "@fintoc/cli@$VERSION" version 2>/dev/null; then
echo "Found @fintoc/cli@$VERSION on npm"
exit 0
fi
echo "Attempt $i/30 - waiting 10s..."
sleep 10
done
echo "Timed out waiting for @fintoc/cli@$VERSION on npm"
npm view "@fintoc/cli" versions --json || true
exit 1

- name: Download tarball and compute SHA256
id: sha
run: |
VERSION="${{ needs.checks.outputs.version }}"
URL="https://registry.npmjs.org/@fintoc/cli/-/cli-${VERSION}.tgz"
TARBALL=$(mktemp)
HTTP_CODE=$(curl -sL -o "$TARBALL" -w '%{http_code}' "$URL")
if [ "$HTTP_CODE" != "200" ]; then
echo "Failed to download tarball (HTTP $HTTP_CODE)"
exit 1
fi
SHA256=$(sha256sum "$TARBALL" | awk '{print $1}')
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
echo "url=$URL" >> "$GITHUB_OUTPUT"

- name: Clone homebrew-tap
uses: actions/checkout@v4
- uses: fintoc-com/release-action/finalize@main
with:
repository: fintoc-com/homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
path: homebrew-tap

- name: Update formula
env:
TARBALL_URL: ${{ steps.sha.outputs.url }}
TARBALL_SHA256: ${{ steps.sha.outputs.sha256 }}
VERSION: ${{ needs.checks.outputs.version }}
run: |
for var in TARBALL_URL TARBALL_SHA256 VERSION; do
[ -z "${!var}" ] && echo "::error::$var is empty" && exit 1
done
envsubst '$TARBALL_URL $TARBALL_SHA256 $VERSION' > homebrew-tap/Formula/fintoc.rb <<'RUBY'
class Fintoc < Formula
desc "CLI for the Fintoc API"
homepage "https://github.com/fintoc-com/fintoc-cli"
url "$TARBALL_URL"
version "$VERSION"
sha256 "$TARBALL_SHA256"
license "BSD-3-Clause"

depends_on "node"

def install
system "npm", "install", *std_npm_args
bin.install_symlink Dir["#{libexec}/bin/*"]
end

test do
assert_match "fintoc/#{version}", shell_output("#{bin}/fintoc --version")
end
end
RUBY

- name: Commit and push
run: |
VERSION="${{ needs.checks.outputs.version }}"
cd homebrew-tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/fintoc.rb
if git diff --cached --quiet; then
echo "Formula already up to date"
exit 0
fi
git commit -m "fintoc $VERSION" -m "https://github.com/fintoc-com/fintoc-cli/releases/tag/v$VERSION"
git push

tag:
needs: [checks, publish]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- name: Create and push tag
env:
TAG_NAME: ${{ needs.checks.outputs.tag_name }}
run: |
if git ls-remote --exit-code --tags origin "refs/tags/$TAG_NAME" >/dev/null 2>&1; then
echo "::error::Tag $TAG_NAME already exists"
exit 1
fi
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
tag: ${{ steps.prep.outputs.tag }}
release-notes: ${{ inputs.release-notes }}
app-id: ${{ vars.FIN_RELEASES_APP_ID }}
app-private-key: ${{ secrets.FIN_RELEASES_PRIVATE_KEY }}
64 changes: 64 additions & 0 deletions .github/workflows/update-homebrew.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Update Homebrew tap

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Versión a sincronizar (default: último release publicado)'
required: false
type: string

jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Resolve version
id: ver
env:
RAW_VERSION: ${{ inputs.version || github.event.release.tag_name }}
run: ./.github/scripts/update-homebrew/resolve-version.sh

- name: Wait for npm publish
env:
VERSION: ${{ steps.ver.outputs.version }}
run: ./.github/scripts/update-homebrew/wait-npm.sh

- name: Download tarball and compute SHA256
id: sha
env:
VERSION: ${{ steps.ver.outputs.version }}
run: ./.github/scripts/update-homebrew/download-tarball.sh

- name: Generate App token for homebrew-tap
id: tap-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.FIN_RELEASES_APP_ID }}
private-key: ${{ secrets.FIN_RELEASES_PRIVATE_KEY }}
owner: fintoc-com
repositories: homebrew-tap

- name: Clone homebrew-tap
uses: actions/checkout@v4
with:
repository: fintoc-com/homebrew-tap
token: ${{ steps.tap-token.outputs.token }}
path: homebrew-tap

- name: Update formula
env:
TARBALL_URL: ${{ steps.sha.outputs.url }}
TARBALL_SHA256: ${{ steps.sha.outputs.sha256 }}
VERSION: ${{ steps.ver.outputs.version }}
run: ./.github/scripts/update-homebrew/update-formula.sh

- name: Commit and push
env:
APP_SLUG: ${{ steps.tap-token.outputs.app-slug }}
TOKEN: ${{ steps.tap-token.outputs.token }}
VERSION: ${{ steps.ver.outputs.version }}
run: ./.github/scripts/update-homebrew/commit-push.sh
Loading
Loading