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
99 changes: 99 additions & 0 deletions .github/workflows/bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: write
outputs:
tag: ${{ steps.version.outputs.tag }}
steps:
- uses: actions/checkout@v6
with:
Expand Down Expand Up @@ -48,3 +50,100 @@ jobs:
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag ${{ steps.version.outputs.tag }}
git push origin ${{ steps.version.outputs.tag }}

build:
name: Build (${{ matrix.os }}/${{ matrix.arch }})
runs-on: ubuntu-latest
needs: bump
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
strategy:
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
steps:
- uses: actions/checkout@v6
with:
ref: ${{ needs.bump.outputs.tag }}
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
- name: Build
run: |
GOOS=${{ matrix.os }}
GOARCH=${{ matrix.arch }}
BINARY_NAME=aperiodic
if [ "$GOOS" = "windows" ]; then BINARY_NAME=aperiodic.exe; fi
mkdir -p dist
GOARCH=$GOARCH GOOS=$GOOS go build -o dist/aperiodic-$GOOS-$GOARCH${BINARY_NAME#aperiodic} ./cmd/aperiodic
- name: Upload artifact
uses: actions/upload-artifact@v6
with:
name: aperiodic-${{ matrix.os }}-${{ matrix.arch }}
path: dist/

release:
name: Publish Release
runs-on: ubuntu-latest
needs: [bump, build]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
- name: Prepare assets
run: |
mkdir -p release
cp artifacts/aperiodic-*/* release/
ls -l release/
# Immutable releases reject asset uploads after publication, so the assets
# have to be attached while the release is still a draft.
- name: Create draft release with assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.bump.outputs.tag }}
run: |
gh release create "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--draft \
--title "$TAG" \
--generate-notes \
release/*
- name: Verify assets are attached
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.bump.outputs.tag }}
run: |
EXPECTED=$(find release/ -type f | wc -l | tr -d " ")
ACTUAL=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" \
--json assets --jq '.assets | length')
echo "Expected $EXPECTED assets, found $ACTUAL"
if [ "$EXPECTED" -ne "$ACTUAL" ]; then
echo "::error::Draft release is missing assets; refusing to publish."
exit 1
fi
- name: Publish release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.bump.outputs.tag }}
run: |
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --draft=false

notify-failure:
name: 🚨 PagerDuty Alert
needs: [bump, build, release]
if: >-
always() &&
contains(join(needs.*.result, ','), 'failure')
runs-on: ubuntu-latest
steps:
- name: Send PagerDuty alert
uses: Entle/action-pagerduty-alert@1.0.5
with:
pagerduty-integration-key: '${{ secrets.PAGERDUTY_INTEGRATION_KEY }}'
pagerduty-dedup-key: aperiodic-cli-release-failure
25 changes: 0 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,3 @@ jobs:
with:
name: aperiodic-${{ matrix.os }}-${{ matrix.arch }}
path: dist/

release:
name: Release
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
- name: Prepare assets
run: |
mkdir -p release
cp artifacts/aperiodic-*/* release/
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: release/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26 changes: 22 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,32 @@ else
URL="https://github.com/$REPO/releases/download/$VERSION/aperiodic-$OS-$ARCH$EXT"
fi

INSTALL_DIR="/usr/local/bin"
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"

echo "Detected OS: $OS, Architecture: $ARCH"
echo "Downloading Aperiodic CLI from $URL..."

TMP_FILE=$(mktemp)
if ! curl -L -o "$TMP_FILE" "$URL"; then
echo "Error: Failed to download binary. Please check the repository and version."
rm -f "$TMP_FILE"
cleanup() { rm -f "$TMP_FILE"; }
trap cleanup EXIT

# -f makes curl exit non-zero on 404 instead of writing the error body to disk.
if ! curl -fL -o "$TMP_FILE" "$URL"; then
echo "Error: Failed to download binary from $URL" >&2
echo "The release may not exist, or it may not have assets for $OS-$ARCH." >&2
echo "See https://github.com/$REPO/releases for available versions." >&2
exit 1
fi

# Guard against a truncated or non-binary download slipping through.
if [ ! -s "$TMP_FILE" ]; then
echo "Error: Downloaded file is empty. Aborting." >&2
exit 1
fi

if head -c 1024 "$TMP_FILE" | LC_ALL=C grep -qi '<!doctype\|<html\|^Not Found'; then
echo "Error: Download did not return a binary (got an HTML or error page)." >&2
echo "URL: $URL" >&2
exit 1
fi

Expand All @@ -55,5 +72,6 @@ if [ -w "$INSTALL_DIR" ]; then
else
sudo mv "$TMP_FILE" "$INSTALL_DIR/$BINARY_NAME"
fi
trap - EXIT

echo "Installation complete. Run 'aperiodic' to get started."