A project for managing repository releases, such as GitHub releases.
This project provides CI templates, scripts, and cmdlets that other projects can utilize for generating release notes and creating releases.
PSRepositoryReleaseManager
can be used as an independent project, or as a submodule for generating release notes and creating releases.
To use PSRepositoryReleaseManager
as an independent project, simply clone a copy of the repository including its submodules to development or CI environment(s) prior to executing generate and release steps.
# Clone the repository with its submodules
git clone https://github.com/theohbrothers/PSRepositoryReleaseManager.git --recurse-submodules
To use PSRepositoryReleaseManager
as a submodule, main projects are to adopt the following directory structure:
/build/ # Directory containing build files
/build/PSRepositoryReleaseManager/ # The root directory of PSRepositoryReleaseManager as a submodule
Add PSRepositoryReleaseManager
as a submodule under the directory build
in your main project:
# Add the submodule
git submodule add https://github.com/theohbrothers/PSRepositoryReleaseManager.git build/PSRepositoryReleaseManager
# Checkout submodules recursively
git submodule update --init --recursive build/PSRepositoryReleaseManager
# Checkout ref to use
git --git-dir build/PSRepositoryReleaseManager/.git checkout vx.x.x
# Commit the submodule
git commit -am 'Add submodule PSRepositoryReleaseManager vx.x.x'
Decide on which CI provider to use in your main project based on those supported by this project. Setup the CI file(s) for your main project. Then simply reference the relevant CI files of this project from your main project's CI file(s).
Sample CI files can be found here.
Configure the following CI settings for your main project if PSRepositoryReleaseManager
is to be used in a CI environment.
Note: This step is only necessary for creating releases on CI environments.
Add a secret variable GITHUB_API_TOKEN
containing your GitHub API token, ensuring it has write permissions to the repository.
The entrypoint script Invoke-Generate.ps1
is used to generate release notes based off local repositories. To generate one, specify the path to the local repository, the release tag ref, the release notes variant, and the release notes path.
The project also includes .vscode/tasks.json
which allows invocation of Invoke-Generate.ps1
via Build Tasks in VSCode. Simply execute the relevant build task while entering custom or default values per variable prompt.
The names of all release notes variants that can be generated can be found in the module's generate/variants
directory and goes by the convention <VariantName>.ps1
.
At present, generation of release notes is only possible for tags of the format MAJOR.MINOR.PATCH
, prepended with a lowercase v
:
# Valid tags
git tag v0.12.1
git tag v1.0.12
# Invalid tags
git tag v1.0.12-alpha
git tag v1.0.12-beta.1
The entrypoint script Invoke-Release.ps1
can be used to create or simulate the creation of releases for GitHub repositories. Simply specify the relevant values pertaining to the release, and if desired, the path to the file containing the release notes to include with it.
The project provides a set of entrypoint scripts for executing the very same steps for generating release notes and creating releases in CI environments.
To generate release notes, reference the appropriate generate.yml
entrypoint CI template provided by this project from your CI file. The generate step can also be customized through provided parameters.
Generation of release notes is presently limited to the module's valid tags pattern.
Note: Ensure your main project's CI file(s) and/or settings are configured to run CI jobs for tag refs.
To create releases, reference the appropriate release.yml
entrypoint CI template provided by this project from your CI file. The release step can also be customized through provided parameters.
Releases supports all tag refs. Tags need not follow Semantic Versioning though the convention is recommended.
# Entrypoint scripts
Invoke-Generate.ps1 [[-ProjectDirectory] <string>] [-ReleaseTagRef] <string> [[-ReleaseNotesVariant] <string>] [[-ReleaseNotesPath] <string>] [<CommonParameters>]
Invoke-Release.ps1 -Namespace <string> -Repository <string> -ApiKey <string> [-ProjectDirectory <string>] [-TagName <string>] [-Name <string>] [-ReleaseNotesPath <string>] [-Draft <bool>] [-Prerelease <bool>] [-Asset <string>] [<CommonParameters>]
Invoke-Release.ps1 -Namespace <string> -Repository <string> -ApiKey <string> [-ProjectDirectory <string>] [-TagName <string>] [-Name <string>] [-ReleaseNotesContent <string>] [-Draft <bool>] [-Prerelease <bool>] [-Asset <string>] [<CommonParameters>]
# Cmdlets
Generate-ReleaseNotes [-Path] <string> [-TagName] <string> [-Variant] {Changes-HashSubject-Merges | Changes-HashSubject-NoMerges | Changes-HashSubject | VersionDate-HashSubject-Merges | VersionDate-HashSubject-NoMerges | VersionDate-HashSubject | VersionDate-Subject-Merges | VersionDate-Subject-NoMerges | VersionDate-Subject} [-ReleaseNotesPath] <string> [<CommonParameters>]
Create-GitHubRelease -Namespace <string> -Repository <string> -ApiKey <string> [-TagName <string>] [-TargetCommitish <string>] [-Name <string>] [-ReleaseNotesPath <string>] [-Draft <bool>] [-Prerelease <bool>] [<CommonParameters>]
Create-GitHubRelease -Namespace <string> -Repository <string> -ApiKey <string> [-TagName <string>] [-TargetCommitish <string>] [-Name <string>] [-ReleaseNotesContent <string>] [-Draft <bool>] [-Prerelease <bool>] [<CommonParameters>]
Upload-GitHubReleaseAsset [-UploadUrl] <string> [-Asset] <string[]> [-ApiKey] <string> [<CommonParameters>]
Simply define necessary environment variables and/or parameter values prior to executing the provided entrypoint script(s) within your CI environment to perform their respective functions.
# CI global variables
$env:GITHUB_API_TOKEN = 'xxx' # required for Release
$env:RELEASE_TAG_REF = 'vx.x.x' # required for Generate and Release
# Generate and Release variables
#$env:PROJECT_DIRECTORY = "$(git rev-parse --show-toplevel)" # optional
#$env:RELEASE_NOTES_PATH = "$(git rev-parse --show-toplevel)/.release-notes.md" # optional
# Generate (Generates release notes)
#$env:RELEASE_NOTES_VARIANT='VersionDate-HashSubject-NoMerges' # optional
$private:generateArgs = @{
ReleaseTagRef = $env:RELEASE_TAG_REF
}
if ($env:PROJECT_DIRECTORY) { $private:generateArgs['ProjectDirectory'] = $env:PROJECT_DIRECTORY }
if ($env:RELEASE_NOTES_VARIANT) { $private:generateArgs['ReleaseNotesVariant'] = $env:RELEASE_NOTES_VARIANT }
if ($env:RELEASE_NOTES_PATH) { $private:generateArgs['ReleaseNotesPath'] = $env:RELEASE_NOTES_PATH }
./path/to/PSRepositoryReleaseManager/src/scripts/ci/Invoke-Generate.ps1 @private:generateArgs
# Release (Creates GitHub release)
$env:RELEASE_NAMESPACE = 'mygithubnamespace' # required
$env:RELEASE_REPOSITORY = 'my-project' # required
#$env:RELEASE_NAME = 'My release name' # optional
#$env:RELEASE_NOTES_CONTENT = Get-Content $env:RELEASE_NOTES_PATH -Raw # optional
#$env:RELEASE_DRAFT = 'false' # optional
#$env:RELEASE_PRERELEASE = 'false' # optional
#$env:RELEASE_ASSETS = @('path/to/asset1.tar.gz', 'path/to/asset2.gz', 'path/to/asset3.zip', 'path/to/assets/*.gz', 'path/to/assets/*.zip') # optional
$private:releaseArgs = @{
Namespace = $env:RELEASE_NAMESPACE
Repository = $env:RELEASE_REPOSITORY
ApiKey = $env:GITHUB_API_TOKEN
}
if ($env:PROJECT_DIRECTORY) { $private:generateArgs['ProjectDirectory'] = $env:PROJECT_DIRECTORY }
if ($env:RELEASE_TAG_REF) { $private:releaseArgs['TagName'] = $env:RELEASE_TAG_REF }
if ($env:RELEASE_NAME) { $private:releaseArgs['Name'] = $env:RELEASE_NAME }
if ($env:RELEASE_NOTES_PATH) { $private:releaseArgs['ReleaseNotesPath'] = $env:RELEASE_NOTES_PATH }
elseif ($env:RELEASE_NOTES_CONTENT) { $private:releaseArgs['ReleaseNotesContent'] = $env:RELEASE_NOTES_CONTENT }
if ($env:RELEASE_DRAFT) { $private:releaseArgs['Draft'] = [System.Convert]::ToBoolean($env:RELEASE_DRAFT) }
if ($env:RELEASE_PRERELEASE) { $private:releaseArgs['Prerelease'] = [System.Convert]::ToBoolean($env:RELEASE_PRERELEASE) }
if ($env:RELEASE_ASSETS) { $private:releaseArgs['Asset'] = $env:RELEASE_ASSETS }
./path/to/PSRepositoryReleaseManager/src/scripts/ci/Invoke-Release.ps1 @private:releaseArgs
To update the submodule:
git submodule update --remote --recursive build/PSRepositoryReleaseManager
To use a specific tag of the submodule:
# Checkout ref to use
git --git-dir build/PSRepositoryReleaseManager/.git checkout vx.x.x
# Bump PSRepositoryReleaseManager to the same ref in CI file
vi azure-pipelines.yml
# Commit the submodule and CI file
git commit -am 'Bump PSRepositoryReleaseManager to vx.x.x'
- Use only tag refs of
PSRepositoryReleaseManager
in your main project. - Ensure your main project's CI file(s) is configured to use the CI templates of
PSRepositoryReleaseManager
and that the ref used matches that of thePSRepositoryReleaseManager
submodule used in your main project.