-
Notifications
You must be signed in to change notification settings - Fork 511
Add GitHub Actions workflow for automated NuGet releases with multi-platform builds #1095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
24d651d
Initial plan
Copilot 9001e28
Add GitHub Actions workflow for NuGet releases
Copilot 2feabed
Remove redundant NUGET_API_KEY environment variable
Copilot 2f874ac
Add comment clarifying sort -V usage
Copilot 9238cf1
Move bash logic to C# build targets
Copilot bcf7137
Fix code review issues: use cross-platform git execution
Copilot caa82a6
Remove duplicate entry in documentation
Copilot 7f71f76
Remove SHA from prerelease version, use only commit count
Copilot d5913e8
Fix TESTING.md to use valid version tag format
Copilot 9d6cd93
Use next minor version with beta suffix for prereleases
Copilot 975f5f4
make things async
adamhathcock 091a800
Potential fix for code scanning alert no. 6: Workflow does not contai…
adamhathcock f1b305f
Add matrix build and master branch support to release workflow
Copilot 9794c8b
Remove GitHub release creation - will be done manually
Copilot 29f8b51
Potential fix for code scanning alert no. 7: Workflow does not contai…
adamhathcock 29cb1fe
Update build/Program.cs
adamhathcock 7afa468
Update build/Program.cs
adamhathcock b2f2ea6
fmt
adamhathcock 5d47bfa
Add tag push trigger to workflow
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| # NuGet Release Workflow | ||
|
|
||
| This document describes the automated NuGet release workflow for SharpCompress. | ||
|
|
||
| ## Overview | ||
|
|
||
| The `nuget-release.yml` workflow automatically builds, tests, and publishes SharpCompress packages to NuGet.org when: | ||
| - Changes are pushed to the `master` or `release` branch | ||
| - A version tag (format: `MAJOR.MINOR.PATCH`) is pushed | ||
|
|
||
| The workflow runs on both Windows and Ubuntu, but only the Windows build publishes to NuGet. | ||
|
|
||
| ## How It Works | ||
|
|
||
| ### Version Determination | ||
|
|
||
| The workflow automatically determines the version based on whether the commit is tagged using C# code in the build project: | ||
|
|
||
| 1. **Tagged Release (Stable)**: | ||
| - If the current commit has a version tag (e.g., `0.42.1`) | ||
| - Uses the tag as the version number | ||
| - Published as a stable release | ||
|
|
||
| 2. **Untagged Release (Prerelease)**: | ||
| - If the current commit is NOT tagged | ||
| - Creates a prerelease version based on the next minor version | ||
| - Format: `{NEXT_MINOR_VERSION}-beta.{COMMIT_COUNT}` | ||
| - Example: `0.43.0-beta.123` (if last tag is 0.42.x) | ||
| - Published as a prerelease to NuGet.org (Windows build only) | ||
|
|
||
| ### Workflow Steps | ||
|
|
||
| The workflow runs on a matrix of operating systems (Windows and Ubuntu): | ||
|
|
||
| 1. **Checkout**: Fetches the repository with full history for version detection | ||
| 2. **Setup .NET**: Installs .NET 10.0 | ||
| 3. **Determine Version**: Runs `determine-version` build target to check for tags and determine version | ||
| 4. **Update Version**: Runs `update-version` build target to update the version in the project file | ||
| 5. **Build and Test**: Runs the full build and test suite on both platforms | ||
| 6. **Upload Artifacts**: Uploads the generated `.nupkg` files as workflow artifacts (separate for each OS) | ||
| 7. **Push to NuGet**: (Windows only) Runs `push-to-nuget` build target to publish the package to NuGet.org using the API key | ||
|
|
||
| All version detection, file updates, and publishing logic is implemented in C# in the `build/Program.cs` file using build targets. | ||
|
|
||
| ## Setup Requirements | ||
|
|
||
| ### 1. NuGet API Key Secret | ||
|
|
||
| The workflow requires a `NUGET_API_KEY` secret to be configured in the repository settings: | ||
|
|
||
| 1. Go to https://www.nuget.org/account/apikeys | ||
| 2. Create a new API key with "Push" permission for the SharpCompress package | ||
| 3. In GitHub, go to: **Settings** → **Secrets and variables** → **Actions** | ||
| 4. Create a new secret named `NUGET_API_KEY` with the API key value | ||
|
|
||
| ### 2. Branch Protection (Recommended) | ||
|
|
||
| Consider enabling branch protection rules for the `release` branch to ensure: | ||
| - Code reviews are required before merging | ||
| - Status checks pass before merging | ||
| - Only authorized users can push to the branch | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Creating a Stable Release | ||
|
|
||
| There are two ways to trigger a stable release: | ||
|
|
||
| **Method 1: Push tag to trigger workflow** | ||
| 1. Ensure all changes are committed on the `master` or `release` branch | ||
| 2. Create and push a version tag: | ||
| ```bash | ||
| git checkout master # or release | ||
| git tag 0.43.0 | ||
| git push origin 0.43.0 | ||
| ``` | ||
| 3. The workflow will automatically trigger, build, test, and publish `SharpCompress 0.43.0` to NuGet.org (Windows build) | ||
|
|
||
| **Method 2: Tag after pushing to branch** | ||
| 1. Ensure all changes are merged and pushed to the `master` or `release` branch | ||
| 2. Create and push a version tag on the already-pushed commit: | ||
| ```bash | ||
| git checkout master # or release | ||
| git tag 0.43.0 | ||
| git push origin 0.43.0 | ||
| ``` | ||
| 3. The workflow will automatically trigger, build, test, and publish `SharpCompress 0.43.0` to NuGet.org (Windows build) | ||
|
|
||
| ### Creating a Prerelease | ||
|
|
||
| 1. Push changes to the `master` or `release` branch without tagging: | ||
| ```bash | ||
| git checkout master # or release | ||
| git push origin master # or release | ||
| ``` | ||
| 2. The workflow will automatically: | ||
| - Build and test the project on both Windows and Ubuntu | ||
| - Publish a prerelease version like `0.43.0-beta.456` to NuGet.org (Windows build) | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Workflow Fails to Push to NuGet | ||
|
|
||
| - **Check the API Key**: Ensure `NUGET_API_KEY` is set correctly in repository secrets | ||
| - **Check API Key Permissions**: Verify the API key has "Push" permission for SharpCompress | ||
| - **Check API Key Expiration**: NuGet API keys may expire; create a new one if needed | ||
|
|
||
| ### Version Conflict | ||
|
|
||
| If you see "Package already exists" errors: | ||
| - The workflow uses `--skip-duplicate` flag to handle this gracefully | ||
| - If you need to republish the same version, delete it from NuGet.org first (if allowed) | ||
|
|
||
| ### Build or Test Failures | ||
|
|
||
| - The workflow will not push to NuGet if build or tests fail | ||
| - Check the workflow logs in GitHub Actions for details | ||
| - Fix the issues and push again | ||
|
|
||
| ## Manual Package Creation | ||
|
|
||
| If you need to create a package manually without publishing: | ||
|
|
||
| ```bash | ||
| dotnet run --project build/build.csproj -- publish | ||
| ``` | ||
|
|
||
| The package will be created in the `artifacts/` directory. | ||
|
|
||
| ## Build Targets | ||
|
|
||
| The workflow uses the following C# build targets defined in `build/Program.cs`: | ||
|
|
||
| - **determine-version**: Detects version from git tags and outputs VERSION and PRERELEASE variables | ||
| - **update-version**: Updates VersionPrefix, AssemblyVersion, and FileVersion in the project file | ||
| - **push-to-nuget**: Pushes the generated NuGet packages to NuGet.org (requires NUGET_API_KEY) | ||
|
|
||
| These targets can be run manually for testing: | ||
|
|
||
| ```bash | ||
| # Determine the version | ||
| dotnet run --project build/build.csproj -- determine-version | ||
|
|
||
| # Update version in project file | ||
| VERSION=0.43.0 dotnet run --project build/build.csproj -- update-version | ||
|
|
||
| # Push to NuGet (requires NUGET_API_KEY environment variable) | ||
| NUGET_API_KEY=your-key dotnet run --project build/build.csproj -- push-to-nuget | ||
| ``` | ||
|
|
||
| ## Related Files | ||
|
|
||
| - `.github/workflows/nuget-release.yml` - The workflow definition | ||
| - `build/Program.cs` - Build script with version detection and publishing logic | ||
| - `src/SharpCompress/SharpCompress.csproj` - Project file with version information | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # Testing Guide for NuGet Release Workflow | ||
|
|
||
| This document describes how to test the NuGet release workflow. | ||
|
|
||
| ## Testing Strategy | ||
|
|
||
| Since this workflow publishes to NuGet.org and requires repository secrets, testing should be done carefully. The workflow runs on both Windows and Ubuntu, but only the Windows build publishes to NuGet. | ||
|
|
||
| ## Pre-Testing Checklist | ||
|
|
||
| - [x] Workflow YAML syntax validated | ||
| - [x] Version determination logic tested locally | ||
| - [x] Version update logic tested locally | ||
| - [x] Build script works (`dotnet run --project build/build.csproj`) | ||
|
|
||
| ## Manual Testing Steps | ||
|
|
||
| ### 1. Test Prerelease Publishing (Recommended First Test) | ||
|
|
||
| This tests the workflow on untagged commits to the master or release branch. | ||
|
|
||
| **Steps:** | ||
| 1. Ensure `NUGET_API_KEY` secret is configured in repository settings | ||
| 2. Create a test commit on the `master` or `release` branch (e.g., update a comment or README) | ||
| 3. Push to the `master` or `release` branch | ||
| 4. Monitor the GitHub Actions workflow at: https://github.com/adamhathcock/sharpcompress/actions | ||
| 5. Verify: | ||
| - Workflow triggers and runs successfully on both Windows and Ubuntu | ||
| - Version is determined correctly (e.g., `0.43.0-beta.XXX` if last tag is 0.42.x) | ||
| - Build and tests pass on both platforms | ||
| - Package artifacts are uploaded for both platforms | ||
| - Package is pushed to NuGet.org as prerelease (Windows build only) | ||
|
|
||
| **Expected Outcome:** | ||
| - A new prerelease package appears on NuGet.org: https://www.nuget.org/packages/SharpCompress/ | ||
| - Package version follows pattern: `{NEXT_MINOR_VERSION}-beta.{COMMIT_COUNT}` | ||
|
|
||
| ### 2. Test Tagged Release Publishing | ||
|
|
||
| This tests the workflow when a version tag is pushed. | ||
|
|
||
| **Steps:** | ||
| 1. Prepare the `master` or `release` branch with all desired changes | ||
| 2. Create a version tag (must be a pure semantic version like `MAJOR.MINOR.PATCH`): | ||
| ```bash | ||
| git checkout master # or release | ||
| git tag 0.42.2 | ||
| git push origin 0.42.2 | ||
|
adamhathcock marked this conversation as resolved.
|
||
| ``` | ||
| 3. Monitor the GitHub Actions workflow | ||
| 4. Verify: | ||
| - Workflow triggers and runs successfully on both Windows and Ubuntu | ||
| - Version is determined as the tag (e.g., `0.42.2`) | ||
| - Build and tests pass on both platforms | ||
| - Package artifacts are uploaded for both platforms | ||
| - Package is pushed to NuGet.org as stable release (Windows build only) | ||
|
|
||
| **Expected Outcome:** | ||
| - A new stable release package appears on NuGet.org | ||
| - Package version matches the tag | ||
|
|
||
| ### 3. Test Duplicate Package Handling | ||
|
|
||
| This tests the `--skip-duplicate` flag behavior. | ||
|
|
||
| **Steps:** | ||
| 1. Push to the `release` branch without making changes | ||
| 2. Monitor the workflow | ||
| 3. Verify: | ||
| - Workflow runs but NuGet push is skipped with "duplicate" message | ||
| - No errors occur | ||
|
|
||
| ### 4. Test Build Failure Handling | ||
|
|
||
| This tests that failed builds don't publish packages. | ||
|
|
||
| **Steps:** | ||
| 1. Introduce a breaking change in a test or code | ||
| 2. Push to the `release` branch | ||
| 3. Verify: | ||
| - Workflow runs and detects the failure | ||
| - Build or test step fails | ||
| - NuGet push step is skipped | ||
| - No package is published | ||
|
|
||
| ## Verification | ||
|
|
||
| After each test, verify: | ||
|
|
||
| 1. **GitHub Actions Logs**: Check the workflow logs for any errors or warnings | ||
| 2. **NuGet.org**: Verify the package appears with correct version and metadata | ||
| 3. **Artifacts**: Download and inspect the uploaded artifacts | ||
|
|
||
| ## Rollback/Cleanup | ||
|
|
||
| If testing produces unwanted packages: | ||
|
|
||
| 1. **Prerelease packages**: Can be unlisted on NuGet.org (Settings → Unlist) | ||
| 2. **Stable packages**: Cannot be deleted, only unlisted (use test versions) | ||
| 3. **Tags**: Can be deleted with: | ||
| ```bash | ||
| git tag -d 0.42.2 | ||
| git push origin :refs/tags/0.42.2 | ||
| ``` | ||
|
|
||
| ## Known Limitations | ||
|
|
||
| - NuGet.org does not allow re-uploading the same version | ||
| - Deleted packages on NuGet.org reserve the version number | ||
| - The workflow requires the `NUGET_API_KEY` secret to be set | ||
|
|
||
| ## Success Criteria | ||
|
|
||
| The workflow is considered successful if: | ||
|
|
||
| - ✅ Prerelease versions are published correctly with beta suffix | ||
| - ✅ Tagged versions are published as stable releases | ||
| - ✅ Build and test failures prevent publishing | ||
| - ✅ Duplicate packages are handled gracefully | ||
| - ✅ Workflow logs are clear and informative | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| name: NuGet Release | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - 'master' | ||
| - 'release' | ||
| tags: | ||
| - '[0-9]+.[0-9]+.[0-9]+' | ||
|
|
||
|
adamhathcock marked this conversation as resolved.
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build-and-publish: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| matrix: | ||
| os: [windows-latest, ubuntu-latest] | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 # Fetch all history for versioning | ||
|
|
||
| - uses: actions/setup-dotnet@v5 | ||
| with: | ||
| dotnet-version: 10.0.x | ||
|
|
||
| # Determine version using C# build target | ||
| - name: Determine Version | ||
| id: version | ||
| run: dotnet run --project build/build.csproj -- determine-version | ||
|
adamhathcock marked this conversation as resolved.
|
||
|
|
||
| # Update version in project file using C# build target | ||
| - name: Update Version in Project | ||
| run: dotnet run --project build/build.csproj -- update-version | ||
| env: | ||
| VERSION: ${{ steps.version.outputs.version }} | ||
|
|
||
| # Build and test | ||
| - name: Build and Test | ||
| run: dotnet run --project build/build.csproj | ||
|
|
||
|
adamhathcock marked this conversation as resolved.
|
||
| # Upload artifacts for verification | ||
| - name: Upload NuGet Package | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: ${{ matrix.os }}-nuget-package | ||
| path: artifacts/*.nupkg | ||
|
|
||
| # Push to NuGet.org using C# build target (Windows only) | ||
| - name: Push to NuGet | ||
| if: success() && matrix.os == 'windows-latest' | ||
| run: dotnet run --project build/build.csproj -- push-to-nuget | ||
| env: | ||
| NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ tests/TestArchives/*/Scratch2 | |
| .vs | ||
| tools | ||
| .idea/ | ||
| artifacts/ | ||
|
|
||
| .DS_Store | ||
| *.snupkg | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.