diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml new file mode 100644 index 0000000..f2f209d --- /dev/null +++ b/.github/workflows/build-and-release.yml @@ -0,0 +1,92 @@ +name: Build and Release + +on: + push: + branches: [ main ] + workflow_dispatch: + inputs: + create_release: + description: 'Create a GitHub release' + required: false + default: false + type: boolean + +jobs: + build: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.nbgv.outputs.SemVer2 }} + should_release: ${{ steps.check-release.outputs.should_release }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for GitVersioning + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + + - name: Install nbgv tool + run: dotnet tool install -g nbgv + + - name: Get version + id: nbgv + run: | + VERSION=$(nbgv get-version --format json | jq -r '.SemVer2') + echo "SemVer2=$VERSION" >> $GITHUB_OUTPUT + echo "Version: $VERSION" + + - name: Check if this is a release + id: check-release + run: | + # Check if tag already exists + if git rev-parse "v${{ steps.nbgv.outputs.SemVer2 }}" >/dev/null 2>&1; then + echo "Tag v${{ steps.nbgv.outputs.SemVer2 }} already exists" + echo "should_release=false" >> $GITHUB_OUTPUT + else + # Release if manually triggered or if this is a non-prerelease version on main + if [[ "${{ github.event.inputs.create_release }}" == "true" ]] || [[ "${{ github.ref }}" == "refs/heads/main" && "${{ steps.nbgv.outputs.SemVer2 }}" != *"-"* ]]; then + echo "should_release=true" >> $GITHUB_OUTPUT + else + echo "should_release=false" >> $GITHUB_OUTPUT + fi + fi + + - name: Restore dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration Release --no-restore + + - name: Publish executables + if: steps.check-release.outputs.should_release == 'true' + run: | + dotnet publish src/GithubRepoRemover/GithubRepoRemover.csproj -c Release -r win-x64 -p:PublishSingleFile=true -o dist/win-x64 + dotnet publish src/GithubRepoRemover/GithubRepoRemover.csproj -c Release -r osx-x64 -p:PublishSingleFile=true -o dist/osx-x64 + dotnet publish src/GithubRepoRemover/GithubRepoRemover.csproj -c Release -r osx-arm64 -p:PublishSingleFile=true -o dist/osx-arm64 + dotnet publish src/GithubRepoRemover/GithubRepoRemover.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -o dist/linux-x64 + + - name: Rename executables + if: steps.check-release.outputs.should_release == 'true' + run: | + mv dist/win-x64/GithubRepoRemover.exe dist/github-repo-remover-win-x64.exe + mv dist/osx-x64/GithubRepoRemover dist/github-repo-remover-osx-x64 + mv dist/osx-arm64/GithubRepoRemover dist/github-repo-remover-osx-arm64 + mv dist/linux-x64/GithubRepoRemover dist/github-repo-remover-linux-x64 + + - name: Create GitHub Release + if: steps.check-release.outputs.should_release == 'true' + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{ steps.nbgv.outputs.SemVer2 }} + name: Release v${{ steps.nbgv.outputs.SemVer2 }} + generate_release_notes: true + files: | + dist/github-repo-remover-win-x64.exe + dist/github-repo-remover-osx-x64 + dist/github-repo-remover-osx-arm64 + dist/github-repo-remover-linux-x64 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index c7d2e5a..b800059 100644 --- a/README.md +++ b/README.md @@ -13,21 +13,26 @@ A CLI tool for bulk-deleting GitHub repositories with an interactive interface. ## Installation -### Download and run (recommended) +### Download Pre-built Executable -No .NET installation required! Just download the executable for your platform: +Download a pre-built executable for your platform: -1. Head to the [Releases](https://github.com/mtfarkas/GithubRepoRemover/releases) page -2. Download the right file for your system: +1. Go to the [Releases](https://github.com/mtfarkas/GithubRepoRemover/releases) page +2. Download the appropriate executable for your platform: - **Windows**: `github-repo-remover-win-x64.exe` - **macOS**: `github-repo-remover-osx-x64` (Intel) or `github-repo-remover-osx-arm64` (Apple Silicon) - **Linux**: `github-repo-remover-linux-x64` -3. On macOS/Linux, make it executable: `chmod +x github-repo-remover-*` -4. Run it! +3. Make the file executable (macOS/Linux): `chmod +x github-repo-remover-*` -### Build it yourself +**Prerequisites:** +- .NET 9.0 runtime ([download here](https://dotnet.microsoft.com/download/dotnet/9.0)) -Need .NET 9.0 SDK installed: +### Build from Source + +If you prefer to build from source: + +**Prerequisites:** +- .NET 9.0 SDK ```bash git clone https://github.com/mtfarkas/GithubRepoRemover.git @@ -160,25 +165,27 @@ You'll need .NET 9.0 SDK installed, then: 2. Run `dotnet restore` 3. Start hacking! -### Building release executables +### Building Self-Contained Executables -To build the self-contained executables: +To create executables for distribution: ```bash -# Windows -dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true +# Windows x64 +dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true -# macOS Intel -dotnet publish -c Release -r osx-x64 --self-contained -p:PublishSingleFile=true +# macOS x64 (Intel) +dotnet publish -c Release -r osx-x64 -p:PublishSingleFile=true -# macOS Apple Silicon -dotnet publish -c Release -r osx-arm64 --self-contained -p:PublishSingleFile=true +# macOS ARM64 (Apple Silicon) +dotcom publish -c Release -r osx-arm64 -p:PublishSingleFile=true -# Linux -dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true +# Linux x64 +dotnet publish -c Release -r linux-x64 -p:PublishSingleFile=true ``` -Executables end up in `src/GithubRepoRemover/bin/Release/net9.0/{runtime}/publish/` +The executables will be generated in `src/GithubRepoRemover/bin/Release/net9.0/{runtime}/publish/` + +**Note:** These are framework-dependent executables that require .NET 9.0 runtime to be installed on the target machine. ## License diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..54f96b7 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,131 @@ +# Release Process Guide + +**First time setup:** Make sure you have the nbgv tool installed before doing anything else: +```bash +dotnet tool install -g nbgv +``` + +## Quick Reference + +### Check current version +To see what version you’re currently on, just run: +```bash +nbgv get-version +``` + +### Patch release (1.0.0 → 1.0.1) +Want to create a quick patch release? Simply commit and push to main - the version bumps up automatically! + +### Minor release (1.0.x → 1.1.0) +If you’re looking to add some new features but don’t want to change the major version, do this: +```bash +nbgv prepare-release +git checkout main +git merge release/v1.1 +git push +``` + +### Major release (1.x.x → 2.0.0) +Ready to make some breaking changes? Here’s how to bump up the major version: +1. Open up `version.json` and change `"version": "1.0"` to `"version": "2.0"` +2. Commit and push those changes to main + +### Manual release (if things break) +In case of emergencies, you can manually run the GitHub Action: +1. Head over to the [Actions tab](https://github.com/mtfarkas/GithubRepoRemover/actions) +2. Hit "Build and Release" +3. Click "Run workflow" +4. Make sure "Create a GitHub release" is checked +5. Click "Run workflow" again + +## How this works + +### Version numbers +Here's the lowdown on versioning: +- **Patch versions** (1.0.0 → 1.0.1): These tick up automatically with each commit to main +- **Minor versions** (1.0.x → 1.1.0): You’ll use `nbgv prepare-release` for these +- **Major versions** (1.x.x → 2.0.0): A quick edit in `version.json` is all you need + +### When releases happen automatically +The magic happens and releases are created when: +- You push a non-prerelease version to the main branch +- OR you give it a nudge manually with the "create release" option + +### What gets built +Wondering what gets bundled up in each release? You’ll find executables for: +- Windows x64 (`github-repo-remover-win-x64.exe`) +- macOS Intel (`github-repo-remover-osx-x64`) +- macOS Apple Silicon (`github-repo-remover-osx-arm64`) +- Linux x64 (`github-repo-remover-linux-x64`) + +## Step-by-step workflows + +### Hotfix/patch (most common) +If you’re making a quick fix, here’s what to do: +1. Make your changes +2. Commit them: `git commit -m "Fix: whatever you fixed"` +3. Push your changes: `git push` +4. And you’re done! Release is created automatically + +### Feature release +Got a new feature ready? Follow these steps: +1. Make your changes +2. Commit them: `git commit -m "Add: new feature"` +3. Prepare the release with: + ```bash + nbgv prepare-release + ``` +4. Merge the changes back to main: + ```bash + git checkout main + git merge release/v1.1 # (replace with the version it created) + ``` +5. Push it all up: `git push` +6. Done deal! Release gets created automatically + +### Breaking change +Making a breaking change? Here’s the process: +1. Update `version.json` to bump the major version: + ```json + { + "version": "2.0", + // ... rest stays the same + } + ``` +2. Commit your changes: `git commit -m "BREAKING: what changed"` +3. Push it all: `git push` +4. That’s it! Release is created automatically + +## Manual release script + +Need to create a tag manually? Maybe testing or automation hiccuped? Here’s how: +```powershell +# First, see what would happen without actually doing it +.\scripts\create-release.ps1 -WhatIf + +# If all looks good, go ahead and create the tag +.\scripts\create-release.ps1 +``` + +## When things go wrong + +### "Tag already exists" error +If you hit a "Tag already exists" error, it means the GitHub Action is trying to avoid duplicate releases. To sort this out: +1. Delete the problematic tag: `git tag -d v1.0.1 && git push origin :v1.0.1` +2. Manually delete the GitHub release +3. Either push your changes again or rerun the action manually + +### Version not incrementing +Not seeing the version increment? Check if you have new commits since the last release. Remember, each commit to main should bump up the patch version. + +### Check what version will be built +Curious about what version is up next? Run: +```bash +nbgv get-version --format json +``` + + +## Useful links +- [GitHub Releases](https://github.com/mtfarkas/GithubRepoRemover/releases) +- [GitHub Actions](https://github.com/mtfarkas/GithubRepoRemover/actions) +- [Nerdbank.GitVersioning docs](https://github.com/dotnet/Nerdbank.GitVersioning) \ No newline at end of file diff --git a/scripts/create-release.ps1 b/scripts/create-release.ps1 new file mode 100644 index 0000000..ec365e5 --- /dev/null +++ b/scripts/create-release.ps1 @@ -0,0 +1,30 @@ +# PowerShell script to create a release tag using nbgv +param( + [switch]$WhatIf +) + +# Get the current version from nbgv +$version = nbgv get-version --format json | ConvertFrom-Json +$versionString = $version.SemVer2 + +Write-Host "Current version: $versionString" -ForegroundColor Green + +if ($WhatIf) { + Write-Host "Would create tag: v$versionString" -ForegroundColor Yellow + exit 0 +} + +# Confirm with user +$confirm = Read-Host "Create and push tag v$versionString? (y/N)" +if ($confirm -ne 'y' -and $confirm -ne 'Y') { + Write-Host "Cancelled" -ForegroundColor Red + exit 1 +} + +# Create and push the tag +Write-Host "Creating tag v$versionString..." -ForegroundColor Blue +git tag "v$versionString" +git push origin "v$versionString" + +Write-Host "Tag v$versionString created and pushed!" -ForegroundColor Green +Write-Host "You can now create a GitHub release at: https://github.com/mtfarkas/GithubRepoRemover/releases/new?tag=v$versionString" -ForegroundColor Cyan \ No newline at end of file diff --git a/version.json b/version.json index d9c0df4..9a9068c 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,22 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.0" + "version": "1.0", + "versionHeightOffset": -1, + "publicReleaseRefSpec": [ + "^refs/heads/main$", + "^refs/heads/release/v\\d+\\.\\d+" + ], + "cloudBuild": { + "buildNumber": { + "enabled": true, + "includeCommitId": { + "when": "nonPublicReleaseOnly", + "where": "buildMetadata" + } + } + }, + "release": { + "branchName": "release/v{version}", + "firstUnstableTag": "alpha" + } } \ No newline at end of file