UNPKG

@halospv3/hce.shared-config

Version:

Automate commit message quality, changelogs, and CI/CD releases. Exports a semantic-release shareable configuration deserialized from this package's '.releaserc.yml'. Shared resources for .NET projects are also distributed with this package.

326 lines (257 loc) 10.7 kB
# HCE.Shared ## NOTICE > Activity is held up by a rewrite for the `next/3.0.0` branch. > > A fix for the `2.x` branch may be feasible if all that's wrong is async functions in CJS. The `2.x` release channel will not receive feature updates, but fixes and dependency updates are acceptable. Infrastructure resources shared with other HaloSPV3 repositories. It is recommended to "install" this repo via [Node Package Manager](#npm) ## Usage ### 1. Install `@halospv3/hce.shared-config` This project is packaged and published via NPM. As such... ```sh npm install --save-dev @halospv3/hce.shared-config ``` ### 2. Customize Semantic Release WARNING! Defining a property will _overwrite_ the previous value. Arrays and objects are _not_ merged. You can... - Assign to certain top-level variables (e.g. `options.preset`) to avoid modifying the plugins array. Caveat: only *some* plugins read these properties. - Write your config in MJS; It is recommended you use [deepmerge](https://www.npmjs.com/package/deepmerge) to recursively merge objects and arrays instead of using `extends`. Doing so will allow your IDE to tell you when a shareable config cannot be found. #### Base Config > - Uses the [conventionalcommits preset](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits). > - Releases `main` branch; Pre-releases `develop`. > - Adds and configures [`semantic-release-export-data`](https://github.com/felipecrs/semantic-release-export-data) to export `new-release-published` and `new-release-version` to GitHub Actions' outputs. > - Adds and configures [`@semantic-release/changelog`](https://github.com/semantic-release/changelog) to update CHANGELOG.md. > - Configures [`@semantic-release/git`](https://github.com/semantic-release/git) to add README.md and CHANGELOG.md in a release commit if they have changes. Uses GitHub job's token to commit. > - Configures [`@semantic-release/github`](https://github.com/semantic-release/github) to release all files found in `$PWD/publish`. ##### Usage ```js // releaserc.config.js import hceSharedConfig from "@halospv3/hce.shared-config" // modify it however you wish before the export statement! export default hceSharedConfig; ``` ```js // releaserc.config.js export default { extends: ["@halospv3/hce.shared-config"] } ``` ```json // package.json { "release": { "extends": ["@halospv3/hce.shared-config"] } } ``` #### Dotnet Config > An extension of our base config. > Exports a function with parameters for 'projects to pack' and 'projects to push (to nuget)'. > Although `@halospv3/hce.shared-config/semanticReleaseConfigDotnet` can be used via `extends` and configured via the `PROJECTS_TO_PUBLISH` and `PROJECTS_TO_PACK_AND_PUSH` environment variables, it is recommended to call the function and pass it parameters so errors are caught before they reach production. > > Differences to the base config: > - Utilizes `@semantic-release/exec` for shell commands. > - Executes `dotnet publish` and `dotnet pack` upon the configured projects during the `prepare` step. > - (WIP) Executes `dotnet nuget sign` during `prepare` upon the `dotnet pack` outputs if `projectsToPackAndPush` is not set to `false` (default: `[]`). > - Executes `dotnet nuget push` during the `publish` step. ##### Usage ```js // releaserc.config.js import { getConfig } from "@halospv3/hce.shared-config/semanticReleaseConfigDotnet" /* Caveat: semantic-release will version and release all specified projects under the same Git tags and GitHub releases. * To version and release them separately, use [https://github.com/pmowrer/semantic-release-monorepo](semantic-release-monorepo). */ /* `prepareCmd` will contain command lines to publish * both Library and Sample to your GitHub release. * Their `TargetFrameworks` and `RuntimeIdentifiers` * properties will be evaluated and a command line * will be added for each unique combination, * _regardless of compatibility and intended combinations_. */ const projectsToPublish = [ "./Library/Library.csproj", "./Sample/Sample.csproj" ]; /* * `prepareCmd` will also contain `dotnet pack` and * `dotnet nuget sign` commands to pack Library to a nupkg. * `publishCmd` will contain `dotnet nuget push` commands * to push Library to Nuget.org and GitHub Package Registry. */ const projectsToPackAndPush = ["./Library/Library.csproj"]; // runs getConfig and exports its return value export default getConfig(projectsToPublish, projectsToPackAndPush) ``` ###### `extends` key in a javascript config file Using `extends` is NOT recommended, but I won't stop you. Your projects' paths must be assigned to environment variables. See [Dotnet Config](#dotnet-config). ```js // releaserc.config.js (if {"type": "module"} in package.json) export default { extends: ["@halospv3/hce.shared-config"] } ``` ```js // releaserc.config.js (if {"type": "commonjs"} in package.json) module.exports = { extends: ["@halospv3/hce.shared-config"] } ``` ###### `release` key in package.json ```json // package.json // `npm install --save-dev cross-env` { "scripts":{ "release":"cross-env PROJECTS_TO_PUBLISH=\"./Library/Library.csproj;./Sample/Sample.csproj\" semantic-release" }, "release": { "extends": ["@halospv3/hce.shared-config/semanticReleaseConfigDotnet"] } } ``` --- **Notable Plugin Properties** - [`@semantic-release/commit-analyzer`](https://github.com/semantic-release/commit-analyzer#options) - preset (set to `conventionalcommits`) - parserOpts - releaseRules - [`@semantic-release/release-notes-generator`](https://github.com/semantic-release/release-notes-generator#options) - preset (set to `conventionalcommits`) - parserOpts - writerOpts - [`@semantic-release/changelog`](https://github.com/semantic-release/changelog#options) - changelogFile (default: `'CHANGELOG.md'`) - [`@semantic-release/git`](https://github.com/semantic-release/git#options) - assets (default: `['README.md', 'CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json']`) - `@semantic-release/exec` - prepareCmd - [`@semantic-release/github`](https://github.com/semantic-release/github#options) - assets - draftRelease (default: false) ### 3. Set Up CommitLint ```json // package.json { "commitlint": { "extends": ["@halospv3/hce.shared-config/commitlintConfig"] } } ``` or ```ts /* eslint-disable import/no-default-export */ import commitlintConfig from '@halospv3/hce.shared-config/commitlintConfig'; export default commitlintConfig; ``` Then... ```sh npx husky npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}' ``` ### 4. (dotnet) Add/Edit Directory.Build.props ```xml <Project> <Import Project="$(HCESharedDir)/dotnet/HCE.Shared.targets"/> <PropertyGroup> <RepoRoot Condition="'$(RepoRoot)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), '.git/index'))</RepoRoot> <HCESharedDir Condition="'$(HCESharedDir)' == ''">$(RepoRoot)node_modules/@halospv3/hce.shared-config/</HCESharedDir> <!--<GitVersion_Path Condition="'$(GitVersion_Path)' == ''">Path/To/Your/GitVersion.yml</GitVersion_Path>--> </PropertyGroup> </Project> ``` These may evaluate to the following: | Property | Evaluated Value| | ------------ | -------------- | |`RepoRootDir` | `c:\Repos\HaloSPV3\HCE.Shared\` | |`HCESharedDir`| `c:\Repos\HaloSPV3\HCE.Shared\node_modules\@halospv3\hce.shared-config\` | #### CI/CD-Only Properties > Note: Already included when importing HCE.Shared.targets > If you don't import HCE.Shared.targets, you may import HCE.Shared.CI.props or define your own conditional property group. If you want properties set only in a CI/CD environment (e.g. a GitHub workflow), add the following conditional property group to the props file: ```xml, diff <Project> <PropertyGroup> ... </PropertyGroup> <PropertyGroup Condition=" '$(CI)' == 'true' "> <Configuration>Release</Configuration> <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild> <Deterministic>true</Deterministic> </PropertyGroup> </Project> ``` > Any properties added to this conditional property group will only be evaluated when `$(CI)` is > defined either as a property or as an environment variable. This is most useful for properties > such as `ContinuousIntegrationBuild`. #### GitVersion By default, GitVersion will search only the "current directory" for `GitVersion.yml`. GitVersion has a lesser-known CLI argument, "Path" which allows users to specify the path to `GitVersion.yml`. The NuGet package `GitVersion.MSBuild` exposes this as the read-write property `$(GitVersion_Path)`. If you're satisfied by [dotnet/GitVersion.yml](dotnet/GitVersion.yml), you can configure GitVersion to use this config file. GitVersion does not have 'extend' functionality typical of Node.js packages. You can... ...define it yourself ```xml <Project> <PropertyGroup> <GitVersion_Path>$(ProjectRootDir)/node_modules/@halospv3/hce.shared-config/dotnet/GitVersion.yml</GitVersion_Path> </PropertyGroup> </Project> ``` ...import HCE.Shared.props ```xml <Project> <Import Project="$(HCESharedDir)/dotnet/HCE.Shared.props"> </Project> ``` ...import HCE.Shared.Targets (which imports HCE.Shared.props) ```xml <Project> <Import Project="$(HCESharedDir)/dotnet/HCE.Shared.props"> </Project> ``` ## Tips ### Need your VersionInfo before the actual release? If you want to use this information in other Semantic Release steps, you'll need `semantic-release-export-data`. Run the following to preview the version: ```sh npx semantic-release --dry-run --plugins "@semantic-release/commit-analyzer,semantic-release-export-data" ``` If the first plugin doesn't run into any issues and infers a version bump from unreleased commits, it will print the next version to the console. The [second plugin](https://github.com/felipecrs/semantic-release-export-data#readme) will export the next version and other information as [GitHub Action Step outputs](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-output-as-url). ### Don't intend to publish a Node package? Add the following to `package.json`: ```json { "private": true, } ``` ## WIP ### Reusable, configurable GitHub workflows See callable workflows such as [dotnet-ci](./.github/workflows/dotnet-ci.yml) ```yml jobs: release: steps: - uses: actions/checkout@v3 - name: dotnet build/publish; copy release artifacts to './publish/' uses: ./node_modules/@halospv3/hce.shared/dotnet/.github/workflows/dotnet-release.yml with: projects: - src/lib/lib.csproj - src/lib-sample/sample.csproj ```