Skip to content

fix: parse rsync itemised output safely #10

fix: parse rsync itemised output safely

fix: parse rsync itemised output safely #10

name: Prebuilt Binaries
on:
push:
branches:
- main
- release
- "release-*"
workflow_dispatch:
permissions:
contents: write
concurrency:
group: prebuilt-binaries-${{ github.ref_name }}
cancel-in-progress: true
jobs:
package:
name: Package ${{ github.ref_name }}
if: github.repository == 'stephenlclarke/mac-sync'
runs-on: macos-26
steps:
- name: Checkout mac-sync
uses: actions/checkout@v7
with:
path: mac-sync
fetch-depth: 0
token: ${{ github.token }}
- name: Select package lane
id: lane
shell: bash
run: |
set -euo pipefail
asset_slug="${GITHUB_REF_NAME//\//-}"
formula_slug="$(
printf '%s' "$asset_slug" \
| tr '[:upper:]' '[:lower:]' \
| sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//'
)"
case "${GITHUB_REF_NAME}" in
main)
target="package-release"
asset="mac-sync-main-release-arm64.tar.gz"
release_name="Homebrew main lane prebuilt"
config="release"
lane="main"
formula="mac-sync.rb"
formula_class="MacSync"
formula_name="mac-sync"
label="main lane"
;;
release|release-*)
target="package-release"
asset="mac-sync-${asset_slug}-release-arm64.tar.gz"
release_name="Homebrew ${GITHUB_REF_NAME} branch prebuilt"
config="release"
lane="release"
formula="mac-sync-${formula_slug}.rb"
formula_class="$(python3 -c 'import re, sys; print("MacSync" + "".join(part.capitalize() for part in re.split(r"[^a-zA-Z0-9]+", sys.argv[1]) if part))' "$formula_slug")"
formula_name="mac-sync-${formula_slug}"
label="${GITHUB_REF_NAME} branch"
;;
*)
printf 'Unsupported branch for prebuilt packaging: %s\n' "${GITHUB_REF_NAME}" >&2
exit 1
;;
esac
{
printf 'target=%s\n' "$target"
printf 'asset=%s\n' "$asset"
printf 'release_name=%s\n' "$release_name"
printf 'config=%s\n' "$config"
printf 'lane=%s\n' "$lane"
printf 'formula=%s\n' "$formula"
printf 'formula_class=%s\n' "$formula_class"
printf 'formula_name=%s\n' "$formula_name"
printf 'label=%s\n' "$label"
printf 'asset_slug=%s\n' "$asset_slug"
printf 'tag=homebrew-%s\n' "$asset_slug"
printf 'version=%s-release-%s\n' "$asset_slug" "${GITHUB_SHA:0:12}"
} >> "$GITHUB_OUTPUT"
- name: Build package
run: make "${{ steps.lane.outputs.target }}" MAC_SYNC_ARCHIVE="${RUNNER_TEMP}/${{ steps.lane.outputs.asset }}"
working-directory: mac-sync
env:
MAC_SYNC_BRANCH: ${{ github.ref_name }}
MAC_SYNC_COMMIT: ${{ github.sha }}
MAC_SYNC_LANE: ${{ steps.lane.outputs.lane }}
- name: Test packaged executables
env:
ASSET: ${{ steps.lane.outputs.asset }}
shell: bash
run: |
set -euo pipefail
package_root="$(mktemp -d)"
tar -xzf "${RUNNER_TEMP}/${ASSET}" -C "$package_root"
"$package_root/mac-sync/bin/mac-sync" --help >/dev/null
"$package_root/mac-sync/bin/mac-spinner" --message package-smoke --pending >/dev/null
test -x "$package_root/mac-sync/MacSync.app/Contents/MacOS/MacSync"
test -x "$package_root/mac-sync/MacSync.app/Contents/Resources/mac-sync"
test -f "$package_root/mac-sync/MacSync.app/Contents/Resources/MacSync.icns"
plutil -lint "$package_root/mac-sync/MacSync.app/Contents/Info.plist"
- name: Upload workflow artifact
uses: actions/upload-artifact@v7
with:
name: ${{ steps.lane.outputs.asset }}
path: |
${{ runner.temp }}/${{ steps.lane.outputs.asset }}
${{ runner.temp }}/${{ steps.lane.outputs.asset }}.sha256
- name: Publish branch release assets
env:
GH_TOKEN: ${{ github.token }}
ASSET: ${{ steps.lane.outputs.asset }}
RELEASE_NAME: ${{ steps.lane.outputs.release_name }}
RELEASE_TAG: ${{ steps.lane.outputs.tag }}
shell: bash
working-directory: mac-sync
run: |
set -euo pipefail
notes="$(mktemp)"
{
printf '%s\n\n' "${RELEASE_NAME}"
printf 'Branch: %s\n' "${GITHUB_REF_NAME}"
printf 'Commit: %s\n' "${GITHUB_SHA}"
printf 'Build configuration: %s\n' "${{ steps.lane.outputs.config }}"
} > "$notes"
git tag --force "$RELEASE_TAG" "$GITHUB_SHA"
git push --force origin "refs/tags/${RELEASE_TAG}"
if ! gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
gh release create "$RELEASE_TAG" \
--target "$GITHUB_SHA" \
--title "${RELEASE_NAME}" \
--notes-file "$notes" \
--prerelease
else
gh release edit "$RELEASE_TAG" \
--target "$GITHUB_SHA" \
--title "${RELEASE_NAME}" \
--notes-file "$notes" \
--prerelease
fi
gh release upload "$RELEASE_TAG" \
"${RUNNER_TEMP}/${ASSET}" \
"${RUNNER_TEMP}/${ASSET}.sha256" \
--clobber
- name: Check Homebrew tap token
id: tap-token
env:
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
shell: bash
run: |
set -euo pipefail
if [[ -z "${HOMEBREW_TAP_TOKEN}" ]]; then
printf '::error title=Homebrew tap publish blocked::HOMEBREW_TAP_TOKEN is required to update stephenlclarke/homebrew-tap.\n'
exit 1
fi
printf 'available=true\n' >> "$GITHUB_OUTPUT"
- name: Checkout Homebrew tap
if: steps.tap-token.outputs.available == 'true'
uses: actions/checkout@v7
with:
repository: stephenlclarke/homebrew-tap
path: homebrew-tap
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
- name: Update Homebrew tap formula
if: steps.tap-token.outputs.available == 'true'
env:
ASSET: ${{ steps.lane.outputs.asset }}
FORMULA: ${{ steps.lane.outputs.formula }}
LABEL: ${{ steps.lane.outputs.label }}
RELEASE_TAG: ${{ steps.lane.outputs.tag }}
VERSION: ${{ steps.lane.outputs.version }}
shell: bash
run: |
set -euo pipefail
url="https://github.com/stephenlclarke/mac-sync/releases/download/${RELEASE_TAG}/${ASSET}"
sha256="$(awk '{print $1}' "${RUNNER_TEMP}/${ASSET}.sha256")"
python3 mac-sync/Tools/release/update-homebrew-formula.py \
--formula "homebrew-tap/Formula/${FORMULA}" \
--template "mac-sync/Formula/mac-sync.rb" \
--formula-class "${{ steps.lane.outputs.formula_class }}" \
--url "$url" \
--version "$VERSION" \
--asset "$ASSET" \
--label "$LABEL" \
--sha256 "$sha256"
git -C homebrew-tap diff -- Formula
- name: Commit Homebrew tap update
if: steps.tap-token.outputs.available == 'true'
shell: bash
working-directory: homebrew-tap
run: |
set -euo pipefail
if git diff --quiet -- Formula; then
printf 'Homebrew tap formula already points at %s\n' "${{ steps.lane.outputs.asset }}"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add "Formula/${{ steps.lane.outputs.formula }}"
git commit -m "chore(homebrew): update ${{ github.ref_name }} mac-sync formula"
git push
- name: Verify Homebrew tap installation
if: steps.tap-token.outputs.available == 'true'
env:
HOMEBREW_NO_AUTO_UPDATE: "1"
shell: bash
run: |
set -euo pipefail
brew untap stephenlclarke/tap >/dev/null 2>&1 || true
brew tap stephenlclarke/tap
brew install --formula stephenlclarke/tap/${{ steps.lane.outputs.formula_name }}
brew test stephenlclarke/tap/${{ steps.lane.outputs.formula_name }}