Skip to content
Open
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/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Publish to PyPI

on:
release:
types: [published]

permissions:
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Build package
run: uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
62 changes: 62 additions & 0 deletions .github/workflows/update-homebrew.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Update Homebrew Formula

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version tag (e.g., v0.1.0)"
required: true

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

- name: Determine version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT"
fi

- name: Download and hash release tarball
id: hash
run: |
TAG="${{ steps.version.outputs.tag }}"
URL="https://github.com/microsoft/amplifier/archive/refs/tags/${TAG}.tar.gz"
curl -sL "$URL" -o release.tar.gz
SHA=$(shasum -a 256 release.tar.gz | awk '{print $1}')
echo "sha256=${SHA}" >> "$GITHUB_OUTPUT"
echo "url=${URL}" >> "$GITHUB_OUTPUT"

- name: Update formula
run: |
TAG="${{ steps.version.outputs.tag }}"
VERSION="${TAG#v}"
SHA="${{ steps.hash.outputs.sha256 }}"
URL="${{ steps.hash.outputs.url }}"

FORMULA="homebrew-amplifier/Formula/amplifier.rb"

sed -i "s|url \".*\"|url \"${URL}\"|" "$FORMULA"
sed -i "s|sha256 \".*\"|sha256 \"${SHA}\"|" "$FORMULA"

# Update version if present in the formula
echo "Updated formula to version ${VERSION} (sha256: ${SHA})"

- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
title: "Update Homebrew formula to ${{ steps.version.outputs.tag }}"
body: |
Automated update of the Homebrew formula for Amplifier.

- Version: `${{ steps.version.outputs.tag }}`
- SHA256: `${{ steps.hash.outputs.sha256 }}`
branch: "update-formula-${{ steps.version.outputs.tag }}"
commit-message: "Update Homebrew formula to ${{ steps.version.outputs.tag }}"
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ Amplifier brings AI assistance to your command line with a modular, extensible a
> [!IMPORTANT]
> Amplifier is currently developed and tested on macOS, Linux, and Windows Subsystem for Linux (WSL). Native Windows shells have known issues—use WSL unless you're actively contributing Windows fixes.

### Step 1: Install UV (30 seconds)
### Option A: Install with Homebrew (macOS/Linux)

```bash
brew tap microsoft/amplifier
brew install amplifier
```

### Option B: Install with UV

#### Step 1: Install UV (30 seconds)

```bash
# macOS/Linux/WSL
Expand All @@ -33,13 +42,13 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```

### Step 2: Install Amplifier (30 seconds)
#### Step 2: Install Amplifier (30 seconds)

```bash
uv tool install git+https://github.com/microsoft/amplifier
```

### Step 3: Run Amplifier (30 seconds)
### Run Amplifier

```bash
# First-time wizard (auto-detects missing config)
Expand Down
3 changes: 3 additions & 0 deletions amplifier/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Amplifier AI development platform - modular AI assistant."""

__version__ = "0.1.0"
171 changes: 171 additions & 0 deletions docs/PUBLISHING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Publishing Guide

This guide covers how to publish Amplifier to PyPI and update the Homebrew formula.

## PyPI Trusted Publishing Setup

Amplifier uses GitHub Actions with OpenID Connect (OIDC) for secure, keyless publishing to PyPI. This eliminates the need for API tokens.

### Prerequisites

1. A PyPI account with permissions to create new projects (or manage the `amplifier` project)
2. Admin access to the `microsoft/amplifier` GitHub repository

### Step 1: Create the PyPI Project

1. Go to [PyPI](https://pypi.org/) and log in
2. If this is the first release:
- The project will be created automatically on first publish
- Ensure your PyPI account is verified (email confirmation)

### Step 2: Configure Trusted Publishing on PyPI

1. Go to your PyPI project page (after first release) or pre-register at: https://pypi.org/manage/account/publishing/
2. Navigate to "Publishing" → "Add a new publisher"
3. Fill in the form:
- **PyPI Project Name**: `amplifier`
- **Owner**: `microsoft`
- **Repository name**: `amplifier`
- **Workflow name**: `publish.yml`
- **Environment name**: `pypi` (must match the environment in `.github/workflows/publish.yml`)
4. Click "Add"

### Step 3: Create GitHub Environment

1. Go to GitHub: `https://github.com/microsoft/amplifier/settings/environments`
2. Click "New environment"
3. Name it: `pypi` (must match PyPI configuration)
4. Configure environment protection rules (recommended):
- ✅ Required reviewers (optional but recommended for production)
- ✅ Restrict to specific branches: `main`
5. Click "Save protection rules"

### Step 4: Test the Workflow

1. Create a test release or manually trigger the workflow
2. The workflow should:
- Build the package with `uv build`
- Publish to PyPI using OIDC (no API tokens needed)
- Complete without errors

### Troubleshooting

**Error: "Permission denied" or "OIDC token not found"**
- Ensure the `pypi` environment exists in GitHub
- Verify the workflow has `permissions: id-token: write`
- Check that the environment name matches in both PyPI and GitHub

**Error: "Project does not exist"**
- For first-time publishing, you may need to pre-register the project name on PyPI
- Go to: https://pypi.org/manage/account/publishing/

**Error: "Publishing not configured"**
- Double-check the PyPI trusted publisher settings
- Ensure owner/repo/workflow/environment names match exactly

## Publishing a New Release

### 1. Prepare the Release

```bash
# Ensure all changes are committed and pushed
git checkout main
git pull origin main

# Update version in pyproject.toml if needed
# Update CHANGELOG.md with release notes
```

### 2. Create and Push a Git Tag

```bash
# Create an annotated tag
git tag -a v0.1.0 -m "Release v0.1.0"

# Push the tag
git push origin v0.1.0
```

### 3. Create a GitHub Release

1. Go to: `https://github.com/microsoft/amplifier/releases/new`
2. Select the tag you just created (e.g., `v0.1.0`)
3. Title: `v0.1.0`
4. Description: Copy from CHANGELOG.md or write release notes
5. Click "Publish release"

### 4. Automated Publishing

Once you create a GitHub release:

1. **PyPI Publishing** (`.github/workflows/publish.yml`):
- Triggers automatically on release
- Builds the package with `uv build`
- Publishes to PyPI via trusted publishing
- ✅ Check: https://pypi.org/project/amplifier/

2. **Homebrew Formula Update** (`.github/workflows/update-homebrew.yml`):
- Triggers automatically on release
- Downloads the release tarball
- Calculates SHA256 hash
- Creates a PR to update `homebrew-amplifier/Formula/amplifier.rb`
- ⚠️ Review and merge the auto-generated PR

### 5. Verify the Release

```bash
# Test PyPI installation
uv pip install amplifier
amplifier --version

# Test Homebrew installation (after merging formula PR)
brew update
brew upgrade amplifier
amplifier --version
```

## Homebrew Tap Setup

### First-Time Setup

The Homebrew formula lives in this repo under `homebrew-amplifier/`. After the first release:

1. Create a separate tap repository: `microsoft/homebrew-amplifier`
2. Copy contents from `homebrew-amplifier/` to the new repo
3. Users can then install with:
```bash
brew tap microsoft/amplifier
brew install amplifier
```

### Manual Formula Updates

If the automated workflow fails, update the formula manually:

```bash
# Download and hash the release tarball
VERSION="v0.1.0"
curl -sL "https://github.com/microsoft/amplifier/archive/refs/tags/${VERSION}.tar.gz" | shasum -a 256

# Update homebrew-amplifier/Formula/amplifier.rb
# Replace the url and sha256 values
# Create a PR with the changes
```

## Dependencies

### Publishing Dependencies to PyPI

Before publishing `amplifier` to PyPI, ensure dependencies are also published:

- ✅ `amplifier-core` - Check [PyPI](https://pypi.org/project/amplifier-core/)
- ✅ `amplifier-app-cli` - Check [PyPI](https://pypi.org/project/amplifier-app-cli/)

If dependencies are not on PyPI yet, they must be published first, or keep using git references in `[tool.uv.sources]` for development.

## Security Notes

- ✅ **No API tokens stored** - Trusted publishing uses short-lived OIDC tokens
- ✅ **Environment protection** - GitHub environments add approval gates
- ✅ **Automated formula updates** - Reduces manual errors in SHA256 hashes
- ⚠️ Always verify the SHA256 hash matches the release tarball before merging Homebrew PRs
35 changes: 35 additions & 0 deletions homebrew-amplifier/Formula/amplifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Amplifier < Formula
desc "AI-powered modular development assistant"
homepage "https://github.com/microsoft/amplifier"
url "https://github.com/microsoft/amplifier/archive/refs/tags/v0.1.0.tar.gz"
# TODO: Update SHA256 after v0.1.0 is tagged. Calculate with:
# curl -sL https://github.com/microsoft/amplifier/archive/refs/tags/v0.1.0.tar.gz | shasum -a 256
sha256 "PLACEHOLDER_SHA256"
license "MIT"

head "https://github.com/microsoft/amplifier.git", branch: "main"

depends_on "uv"
depends_on "python@3.12"

# Pre-built Python wheels (e.g. pydantic_core) have compiled extensions
# whose Mach-O headers cannot be rewritten by Homebrew's relocator.
# This is harmless — the extensions work correctly without relocation.
skip_clean "libexec"

def install
python = Formula["python@3.12"].opt_bin/"python3.12"
venv = libexec

# uv sync respects [tool.uv.sources] and uv.lock for reproducible installs
# (including git-sourced packages not yet published to PyPI)
ENV["UV_PROJECT_ENVIRONMENT"] = venv.to_s
system "uv", "sync", "--frozen", "--no-dev", "--python", python

(bin/"amplifier").write_env_script(venv/"bin/amplifier", PATH: "#{venv}/bin:$PATH")
end

test do
assert_match "amplifier", shell_output("#{bin}/amplifier --version")
end
end
41 changes: 41 additions & 0 deletions homebrew-amplifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Homebrew Tap for Amplifier

This is the official [Homebrew](https://brew.sh) tap for [Amplifier](https://github.com/microsoft/amplifier), an AI-powered modular development assistant.

## Installation

```bash
brew tap microsoft/amplifier
brew install amplifier
```

## Updating

```bash
brew update
brew upgrade amplifier
```

## Development Install (HEAD)

To install the latest development version from the `main` branch:

```bash
brew install --HEAD amplifier
```

## Requirements

- macOS or Linux
- Python 3.12+ (installed automatically by Homebrew)
- [uv](https://docs.astral.sh/uv/) (installed automatically by Homebrew)

## Troubleshooting

If you encounter issues, try:

```bash
brew reinstall amplifier
```

Or file an issue at [microsoft/amplifier](https://github.com/microsoft/amplifier/issues).
Loading