diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 0000000..9502fb5 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,38 @@ +name: Prepare Release +on: + workflow_dispatch: + inputs: + release_type: + description: Type of release + type: choice + required: true + options: + - patch + - minor + - major + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Bump Version file + id: bump + run: | + echo "version=$(swift package --allow-writing-to-package-directory version-file --target watcher --bump ${{ inputs.release_type }})" >> $GITHUB_OUTPUT + + - name: Create pull request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + commit-message: Bump Version.swift -> ${{ steps.bump.outputs.version }} + committer: GitHub + author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> + branch: release + delete-branch: true + title: '[CI] Prepare Version ${{ steps.bump.outputs.version }} Release' + body: | + Update `Version.swift` with bumped version number + draft: false diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml new file mode 100644 index 0000000..c683b77 --- /dev/null +++ b/.github/workflows/tag-release.yml @@ -0,0 +1,34 @@ +name: Tag Release +on: + pull_request: + types: + - closed + branches: + - 'main' + +jobs: + tag: + runs-on: ubuntu-latest + if: github.event.pull_request.merged == true && github.head_ref == 'release' + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Get version + id: get-version + shell: bash + run: | + VERSION=$(grep -Eo '([0-9]+\.*)+' ${{ vars.VERSION_FILE_PATH }}) + echo "current-version=$VERSION" >> $GITHUB_ENV + + - name: Push tag + uses: actions/github-script@v6 + with: + github-token: ${{ steps.generate-token.outputs.token }} + script: | + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ env.current-version }}', + sha: '${{ github.sha }}' + }) diff --git a/Package.resolved b/Package.resolved index a3c049f..142eec7 100644 --- a/Package.resolved +++ b/Package.resolved @@ -54,6 +54,15 @@ "version" : "1.0.4" } }, + { + "identity" : "swift-version-file-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mobelux/swift-version-file-plugin", + "state" : { + "revision" : "b5bb65e2166ecf927ad20643e86501d5607f9cfc", + "version" : "0.1.0" + } + }, { "identity" : "yams", "kind" : "remoteSourceControl", diff --git a/Package.swift b/Package.swift index 5927157..4c5b8e2 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,8 @@ let package = Package( .package(url: "https://github.com/apple/swift-async-algorithms", from: "0.1.0"), .package(url: "https://github.com/eonist/FileWatcher.git", from: "0.2.3"), .package(url: "https://github.com/johnsundell/shellout.git", from: "2.3.0"), - .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.4") + .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.4"), + .package(url: "https://github.com/mobelux/swift-version-file-plugin", from: "0.1.0") ], targets: [ .executableTarget( diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..e7ecb34 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,5 @@ +# Release Instructions + +This tool uses the [swift-version-file-plugin](https://github.com/Mobelux/swift-version-file-plugin) Swift Package Manager command plugin to maintain a source file--[`Sources/watcher/Version.swift`](Sources/watcher/Version.swift)--supplying the value that is returned when the tool is run with the `--version` option. To ensure that this is properly maintained, releases should only be created using the [`Prepare Release`](http://github.com/Mobelux/Watcher/actions/workflows/prepare-release.yml) workflow. + +To prepare a new release, run the workflow using `workflow_dispatch` event trigger from the `main` branch with the appropriate release type. This will create a new PR on a `release` branch containing an update to the Version file. Any additional changes related to the release, like updating a changelog, should be added to this PR. Merging the `release` branch into `main` will delete it and trigger the [`Tag Release`](.github/workflows/tag-release.yml) workflow to create a new tag corresponding to the value of the updated Version file. diff --git a/Sources/watcher/Version.swift b/Sources/watcher/Version.swift new file mode 100644 index 0000000..7e54b4b --- /dev/null +++ b/Sources/watcher/Version.swift @@ -0,0 +1,5 @@ +// This file was generated by the `VersionFile` package plugin. + +enum Version { + static let number = "0.0.1" +} diff --git a/Sources/watcher/Watcher.swift b/Sources/watcher/Watcher.swift index 13233df..81d0fc3 100644 --- a/Sources/watcher/Watcher.swift +++ b/Sources/watcher/Watcher.swift @@ -12,6 +12,11 @@ import WatcherCore /// The entry point for the `Watcher` command-line tool. @main struct Watcher: AsyncParsableCommand { + /// Configuration for this command. + static let configuration = CommandConfiguration( + abstract: "Execute commands when watched directories are modified.", + version: Version.number) + /// The path to a configuration file. @Option(name: .shortAndLong, help: "The path to a configuration file.") var config: String? = nil