Skip to content

Commit

Permalink
docs(readme): add detailed setup guide and workflow examples
Browse files Browse the repository at this point in the history
  • Loading branch information
sheerlox committed Nov 20, 2023
1 parent 47b8479 commit 42fe969
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 6 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
> **Warning**
> Publishing to `hex` has not yet been implemented, so this package only bumps the version in `mix.exs` for now.
| Step | Description |
| ------------------ | --------------------------------------------------------------------------- |
| `verifyConditions` | Verify the presence of the `mix.exs` file and that the version is parsable. |
| `prepare` | Update the version in `mix.exs`. |
| _`addChannel`_ | _to be implemented (PRs welcome)_ |
| _`publish`_ | _to be implemented (PRs welcome)_ |
| Step | Description |
| ------------------ | -------------------------------------------------------------------------------------------------------- |
| `verifyConditions` | Verify the presence of the `mix.exs` file and that the version is parsable. |
| `prepare` | Update the version in `mix.exs`. |
| _`publish`_ | _[to be implemented](https://github.com/talent-ideal/semantic-release-hex/discussions/14) (PRs welcome)_ |

## Installation

```shell
npm install semantic-release-hex -D
```

For a more detailed setup guide, see [**Setting up an existing Elixir project**](./docs/SETTING_UP.md).

## Usage

Add the plugin to the [**semantic-release** configuration file](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration) (see example below).
Expand Down
95 changes: 95 additions & 0 deletions docs/SETTING_UP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Setting up an existing Elixir project

## Before we begin

`semantic-release` uses git tags to determine the current version of a project, so you must make sure your latest version is tagged (and pointing to the right commit).

If you are using a different tag format than `v${version}`, see the [`tagFormat` option](https://semantic-release.gitbook.io/semantic-release/usage/configuration#tagformat).

## Install Node.js

You'll need Node.js `>=18.17`.

The recommended way to install it is with the [`asdf`](https://asdf-vm.com/) version manager (which also supports Elixir) by adding it to your [`.tool-versions`](./.tool-versions) and running `asdf install`.

Otherwise, you can [download it from nodejs.org](https://nodejs.org/en/download/).

## Install the tools

Install the required libraries:

```shell
npm i --save-dev semantic-release @semantic-release/changelog @semantic-release/git semantic-release-hex
```

Add `node_modules` to your `.gitignore`:

```shell
echo -e "\n# Node.js dependencies directory\nnode_modules" >> .gitignore
```

## Configuring `semantic-release`

`semantic-release` is [modular](https://semantic-release.gitbook.io/semantic-release/extending/plugins-list), [extendable](https://semantic-release.gitbook.io/semantic-release/developer-guide/plugin) and [configurable to your preferences](https://semantic-release.gitbook.io/semantic-release/usage/configuration). Here we'll setup a workflow for the `main` branch with the following steps:

1. Analyze the commits to determine the version bump type (if any)
2. Generate release notes from the commits
3. Write the release notes to the `CHANGELOG.md` file
4. Bump the version in `mix.exs`
5. Create and push a release commit (with the updated `CHANGELOG.md` and `mix.exs` files)
6. Create a release tag
7. Create a GitHub release

There's [a few ways](https://semantic-release.gitbook.io/semantic-release/usage/configuration#configuration-file) to configure `semantic-release`, but we'll chose to do it in `package.json` to avoid creating an extra file. Add a `release` key as follow:

```json
{
"devDependencies": {...},

"release": {
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"semantic-release-hex",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "mix.exs"],
"message": "chore(release): v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
"@semantic-release/github"
]
}
}
```

_Note: if you want your CHANGELOG to include all commit types (and add a bit of color with category emojis) like the one in this demo, checkout [`@insurgent/conventional-changelog-preset`](https://github.com/insurgent-lab/conventional-changelog-preset#readme)_.

# CI configuration (GitHub Actions)

See [`semantic-release` documentation on CI configuration](https://semantic-release.gitbook.io/semantic-release/recipes/ci-configurations) for general information.

See [`examples/release.yml`](./examples/release.yml) and [`examples/test.yml`](./examples/test.yml) for example workflows in an Elixir project.

**If you use branch protection:** See comments in example release workflow. To generate the `CI_GITHUB_TOKEN` secret needed to bypass branch protection when pushing the release commit, see [this StackOverflow answer](https://stackoverflow.com/questions/74744498/github-pushing-to-protected-branches-with-fine-grained-token/76550826#76550826) on how to create a fine-grained token with the right scopes (I know, I really need to [update the docs](https://github.com/semantic-release/semantic-release/issues/2883)).

# Running from the CLI

_Note: If you're concerned about security, you can run `gh auth refresh` after using `gh auth token` to regenerate [`gh`](https://cli.github.com/)'s token and invalidate the previous one (or you can create a fine-grained token by visiting the StackOverflow link in [CI configuration](#ci-configuration-github-actions))._

## To test everything is working

```shell
GH_TOKEN=$(gh auth token) npx semantic-release --dry-run
```

## To make an actual release

```shell
GH_TOKEN=$(gh auth token) npx semantic-release --no-ci
```

_Note: if your git is configured to automatically sign tags, this won't work [due to a known issue](https://github.com/semantic-release/semantic-release/issues/3065). Run `git config tag.gpgSign false` in your repo first._
51 changes: 51 additions & 0 deletions docs/examples/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Release

on:
push:
branches:
- main
- dev

permissions:
contents: read

jobs:
test:
uses: ./.github/workflows/test.yml
permissions:
contents: read

release:
needs: test

# remove this if you use branch protection
permissions:
contents: write
issues: write
pull-requests: write

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
# uncomment this if you use branch protection
# with:
# persist-credentials: false

- name: Use Node.js LTS
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
with:
node-version-file: ".tool-versions"

- name: Install packages
run: npm ci

- name: Audit npm signatures
run: npm audit signatures

- name: Run Semantic Release
run: npx semantic-release
env:
# replace the secret by CI_GITHUB_TOKEN if you use branch protection
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74 changes: 74 additions & 0 deletions docs/examples/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Test

on:
push:
# ignore branches where the release workflow runs as it already calls this one
branches-ignore:
- main
pull_request:
workflow_call:

permissions:
contents: read

env:
MIX_ENV: test

jobs:
# ignore the push event trigger if a PR is open for the current branch
prevent-duplicate-checks:
runs-on: ubuntu-latest
steps:
- uses: insurgent-lab/is-in-pr-action@78ecb5daf15aca198aeb2b6f208aabd06b2cb716 # v0.1.4
id: isInPR
outputs:
should-run: ${{ !(steps.isInPR.outputs.result == 'true' && github.event_name == 'push') }}

test:
name: Build and test

runs-on: ubuntu-latest
timeout-minutes: 5

needs: prevent-duplicate-checks
if: ${{ needs.prevent-duplicate-checks.outputs.should-run == 'true' }}

steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Set up Elixir
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
with:
version-type: strict
version-file: .tool-versions

- name: Restore dependencies cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
env:
cache-name: mix-deps
with:
path: deps
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-${{ env.cache-name }}-

- name: Restore build cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
env:
cache-name: mix-build
with:
path: _build
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-${{ env.cache-name }}-

- name: Install dependencies
run: mix deps.get

- name: Check formatting
run: mix format --check-formatted

- name: Compile code (without warning) and deps
run: mix compile --warnings-as-errors

- name: Run tests
run: mix test

0 comments on commit 42fe969

Please sign in to comment.