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
69 changes: 69 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ on:
jobs:
build:
runs-on: ubuntu-latest
outputs:
win_x64_sha256: ${{ steps.checksums.outputs.win_x64_sha256 }}
win_arm64_sha256: ${{ steps.checksums.outputs.win_arm64_sha256 }}
linux_x64_sha256: ${{ steps.checksums.outputs.linux_x64_sha256 }}
linux_arm64_sha256: ${{ steps.checksums.outputs.linux_arm64_sha256 }}
osx_x64_sha256: ${{ steps.checksums.outputs.osx_x64_sha256 }}
osx_arm64_sha256: ${{ steps.checksums.outputs.osx_arm64_sha256 }}
permissions:
contents: write

Expand Down Expand Up @@ -52,6 +59,18 @@ jobs:
cd ./publish/linux-arm64 && tar -czf ../../dotnet-api-diff-linux-arm64.tar.gz . && cd ../..
cd ./publish/osx-arm64 && tar -czf ../../dotnet-api-diff-osx-arm64.tar.gz . && cd ../..

- name: Calculate checksums
id: checksums
run: |
{
echo "win_x64_sha256=$(sha256sum "dotnet-api-diff-win-x64.zip" | cut -d' ' -f1)"
echo "win_arm64_sha256=$(sha256sum "dotnet-api-diff-win-arm64.zip" | cut -d' ' -f1)"
echo "linux_x64_sha256=$(sha256sum "dotnet-api-diff-linux-x64.tar.gz" | cut -d' ' -f1)"
echo "linux_arm64_sha256=$(sha256sum "dotnet-api-diff-linux-arm64.tar.gz" | cut -d' ' -f1)"
echo "osx_x64_sha256=$(sha256sum "dotnet-api-diff-osx-x64.tar.gz" | cut -d' ' -f1)"
echo "osx_arm64_sha256=$(sha256sum "dotnet-api-diff-osx-arm64.tar.gz" | cut -d' ' -f1)"
} >> "$GITHUB_OUTPUT"

- name: Create Release
uses: softprops/action-gh-release@v1
with:
Expand All @@ -63,3 +82,53 @@ jobs:
dotnet-api-diff-linux-arm64.tar.gz
dotnet-api-diff-osx-arm64.tar.gz
generate_release_notes: true

chocolatey:
needs: build
runs-on: windows-latest
if: startsWith(github.ref, 'refs/tags/v')

steps:
- uses: actions/checkout@v4

- name: Setup PowerShell
shell: pwsh
run: |
# Install Chocolatey CLI if not present
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}

- name: Build and publish Chocolatey package
shell: pwsh
env:
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
run: |
$version = "${{ github.ref }}" -replace 'refs/tags/v', ''
.\scripts\build-chocolatey.ps1 -Version "$version" -ChecksumX64 "${{ needs.build.outputs.win_x64_sha256 }}" -ChecksumArm64 "${{ needs.build.outputs.win_arm64_sha256 }}" -ApiKey "$env:CHOCOLATEY_API_KEY" -Publish

homebrew:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')

steps:
- uses: actions/checkout@v4

- name: Get release version
id: release_info
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Update Homebrew formula
run: |
./scripts/update-homebrew.sh "${{ steps.release_info.outputs.version }}" "${{ needs.build.outputs.osx_arm64_sha256 }}" "${{ needs.build.outputs.osx_x64_sha256 }}" "${{ needs.build.outputs.linux_arm64_sha256 }}" "${{ needs.build.outputs.linux_x64_sha256 }}"

- name: Upload Homebrew formula as artifact
uses: actions/upload-artifact@v4
with:
name: homebrew-formula
path: artifacts/dotnetapidiff.rb
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,8 @@ node_modules/

# Local History for Visual Studio
.localhistory/test-report/

glide-testing/

# Package build directories
build/
artifacts/
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,21 @@ task ci

### Installation

#### Quick Install (Linux/macOS)
#### Package Managers (Recommended)

**Windows (Chocolatey):**

```powershell
choco install dotnetapidiff
```

**macOS/Linux (Homebrew):**

```bash
brew install dotnetapidiff
```

#### Quick Install Script (Linux/macOS)

```bash
# Install latest version to user directory
Expand Down
199 changes: 199 additions & 0 deletions docs/package-manager-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Package Manager Setup Guide

This document explains how to set up automated publishing to Chocolatey and Homebrew package managers for DotNet API Diff releases.

## Overview

The release workflow automatically builds and publishes packages to:

- **Chocolatey** (Windows package manager)
- **Homebrew** (macOS/Linux package manager)

## Prerequisites

### Repository Secrets

The following secrets must be configured in the GitHub repository settings:

1. **CHOCOLATEY_API_KEY**: API key for publishing to Chocolatey

### Package Manager Accounts

#### Chocolatey Setup

1. **Create Chocolatey Account**:
- Visit [Chocolatey Community](https://community.chocolatey.org/)
- Create an account or sign in
- Navigate to your profile and generate an API key

2. **Package Registration**:
- The first package version must be manually submitted for approval
- Subsequent versions will be automatically published via the API
- Package ID: `dotnetapidiff`

3. **Configure GitHub Secret**:

```bash
# In GitHub repository settings > Secrets and variables > Actions
# Add new repository secret:
Name: CHOCOLATEY_API_KEY
Value: [Your Chocolatey API key]
```

#### Homebrew Setup

Homebrew publishing is currently handled by generating an updated formula that can be:

1. **Submitted to homebrew-core** (requires community approval)
2. **Published to a custom tap** (immediate publishing)

For custom tap approach:

1. Create a repository named `homebrew-dotnetapidiff`
2. The workflow generates the updated formula as an artifact
3. Manually or automatically commit the formula to the tap repository

## Workflow Details

### Chocolatey Publishing

The workflow automatically:

1. Builds Windows x64 and ARM64 binaries
2. Calculates SHA256 checksums
3. Creates a Chocolatey package (.nupkg)
4. Publishes to Chocolatey Community using the API key

**Package Structure:**

```text
dotnetapidiff/
β”œβ”€β”€ tools/
β”‚ β”œβ”€β”€ chocolateyinstall.ps1 # Installation script
β”‚ β”œβ”€β”€ chocolateyuninstall.ps1 # Uninstallation script
β”‚ └── dotnetapidiff.bat # Command wrapper
└── dotnetapidiff.nuspec # Package metadata
```

### Homebrew Formula

The workflow automatically:

1. Downloads all platform binaries (macOS/Linux, x64/ARM64)
2. Calculates SHA256 checksums for each platform
3. Generates an updated Homebrew formula with correct URLs and checksums
4. Uploads the formula as a build artifact

**Formula Features:**

- Platform detection (macOS/Linux, Intel/ARM)
- Automatic binary selection based on platform
- SHA256 verification
- Installs binary as `dotnetapidiff`

## Package Testing

### Chocolatey Testing

```powershell
# Install package
choco install dotnetapidiff

# Test installation
dotnetapidiff --version

# Uninstall
choco uninstall dotnetapidiff
```

### Homebrew Testing

```bash
# Install from custom tap (if using tap approach)
brew tap jbrinkman/dotnetapidiff
brew install dotnetapidiff

# Test installation
dotnetapidiff --version

# Uninstall
brew uninstall dotnetapidiff
```

## Manual Package Creation

For testing or manual publishing:

### Chocolatey

```powershell
# Build package locally
.\scripts\build-chocolatey.ps1 -Version "1.0.0" -ChecksumX64 "abc123..." -ChecksumArm64 "def456..."

# Test package locally
choco install .\build\chocolatey\dotnetapidiff.1.0.0.nupkg

# Publish manually
.\scripts\build-chocolatey.ps1 -Version "1.0.0" -ChecksumX64 "abc123..." -ChecksumArm64 "def456..." -ApiKey "your-api-key" -Publish
```

### Homebrew

```bash
# Generate formula
./scripts/update-homebrew.sh "1.0.0" "osx_arm64_hash" "osx_x64_hash" "linux_arm64_hash" "linux_x64_hash"

# Test formula (if brew is available)
brew install ./build/homebrew/dotnetapidiff.rb
```

## Troubleshooting

### Common Issues

1. **Chocolatey API Key Invalid**:
- Verify the API key in repository secrets
- Check if the key has expired or been revoked

2. **Package Approval Required**:
- First-time packages on Chocolatey require manual approval
- Check the package status on Chocolatey Community

3. **Checksum Mismatch**:
- Ensure release assets are fully uploaded before package creation
- Verify download URLs are accessible

4. **Homebrew Formula Validation Fails**:
- Check formula syntax using `brew audit`
- Ensure all download URLs are valid and accessible

### Debugging

1. **Check Workflow Logs**:
- GitHub Actions logs show detailed error messages
- Look for failed steps in package publishing jobs

2. **Test Locally**:
- Run packaging scripts manually with test data
- Verify package installation on target platforms

3. **Package Manager Status**:
- Check package status on Chocolatey Community
- Verify formula syntax and platform support

## Security Considerations

1. **API Key Management**:
- Store API keys only in GitHub repository secrets
- Regularly rotate API keys
- Limit API key permissions to package publishing only

2. **Package Integrity**:
- All packages include SHA256 checksums
- Binaries are built from tagged releases only
- Package contents are validated during build

3. **Automated Publishing**:
- Only triggered on tagged releases (v*.*)
- Requires successful build and test completion
- Includes rollback strategies for failed publications
Binary file added icons/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions packaging/chocolatey/dotnetapidiff.nuspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>dotnetapidiff</id>
<version>$version$</version>
<packageSourceUrl>https://github.com/jbrinkman/dotnet-api-diff</packageSourceUrl>
<owners>jbrinkman</owners>
<title>DotNet API Diff</title>
<authors>Josh Brinkman</authors>
<projectUrl>https://github.com/jbrinkman/dotnet-api-diff</projectUrl>
<iconUrl>https://cdn.statically.io/gh/jbrinkman/dotnet-api-diff/main/icons/icon128.png</iconUrl>
<copyright>2025 Josh Brinkman</copyright>
<licenseUrl>https://github.com/jbrinkman/dotnet-api-diff/blob/main/LICENSE</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/jbrinkman/dotnet-api-diff</projectSourceUrl>
<docsUrl>https://github.com/jbrinkman/dotnet-api-diff/blob/main/README.md</docsUrl>
<bugTrackerUrl>https://github.com/jbrinkman/dotnet-api-diff/issues</bugTrackerUrl>
<tags>dotnet api diff compare assembly compatibility breaking-changes cli tool</tags>
<summary>A command-line tool for comparing .NET assemblies and detecting API differences and breaking changes.</summary>
<description><![CDATA[
DotNet API Diff is a powerful command-line tool designed to compare .NET assemblies and identify API differences, including breaking changes. It's particularly useful for library maintainers, API designers, and development teams who need to ensure backward compatibility when releasing new versions of their .NET libraries.

## Features

- **Comprehensive API Analysis**: Detects additions, removals, and modifications in types, methods, properties, and other API members
- **Breaking Change Detection**: Identifies changes that could break existing client code
- **Flexible Configuration**: Supports custom mappings, exclusions, and comparison rules via JSON configuration files
- **Multiple Output Formats**: Console, JSON, and other formats for integration with CI/CD pipelines
- **Cross-Platform**: Runs on Windows, macOS, and Linux
- **Fast and Reliable**: Built with .NET 8 for optimal performance

## Use Cases

- **Library Versioning**: Validate that new library versions maintain backward compatibility
- **API Migration**: Compare APIs when migrating between different libraries or versions
- **CI/CD Integration**: Automate API compatibility checks in your build pipeline
- **Documentation**: Generate change logs and migration guides based on API differences

## Installation

Once installed via Chocolatey, you can use the tool from any command prompt or PowerShell window:

```
dotnetapidiff --help
```

## Basic Usage

```
# Compare two assembly files
dotnetapidiff compare old-assembly.dll new-assembly.dll

# Use a configuration file for advanced scenarios
dotnetapidiff compare old-assembly.dll new-assembly.dll --config myconfig.json

# Output results in JSON format
dotnetapidiff compare old-assembly.dll new-assembly.dll --output json
```

For more information, visit the project repository at https://github.com/jbrinkman/dotnet-api-diff
]]> </description>
<releaseNotes>See release notes at https://github.com/jbrinkman/dotnet-api-diff/releases</releaseNotes>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
Loading
Loading