A complete guide to use dependabot with semantic-release and @vercel/ncc for GitHub Actions

It is also easy to set up, however, it provides no chance to run a command in the PR, so we have additional considerations if we have some pre-release processes. For instance, for a GitHub Actions repository, we want to keep the dist directory updated by @vercel/ncc right after we update its dependencies.

This article introduces semantic-release as a solution. It automates the release process, and its exec plugin helps us to run @vercel/ncc before the release automatically.

Overview of the development process is like below:

  1. Dependabot creates a PR to update dependencies
  2. GitHub Actions test the change, and reflect its result to GitHub Checks
  3. Merge the PR manually or automatically
  4. GitHub Actions run on the default branch, and trigger the semantic-release
  5. semantic-release creates a Git tag, a GitHub Release, and a npm release

Check the following chapters for detail, or refer to my GitHub repo as a working example.

Install necessary node packages

Make sure you have a npm project in your working directory, and run the following command to install semantic-release and its plugins:

npm add -D semantic-release @semantic-release/exec @semantic-release/git

Configure npm to run @vercel/ncc

In package.json, confirm that we have a script to run ncc to optimize JS files like below:

"scripts": {
    "package": "ncc build --source-map"
  }

Configure semantic-release

Follow the official documents to configure semantic-release.

In my case, it became like below to use the main branch as default branch, and run exec plugin and git plugin:

"release": {
    "branches": "main",
    "plugins": [
      "@semantic-release/commit-analyzer",
      "@semantic-release/release-notes-generator",
      "@semantic-release/npm",
      "@semantic-release/github",
      ["@semantic-release/exec", {
        "prepare": "npm run package"
      }],
      [
        "@semantic-release/git",
        {
          "assets": [
            "dist",
            "package.json",
            "package-lock.json"
          ],
          "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
        }
      ]
    ]
  }

Configure the dependabot to follow the Conventional Commit

Configure .github/dependabot.yml to enable dependabot. Make sure commit-message part is configured with prefix: fix to following the Conventional Commits.

version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: daily
    commit-message:
      prefix: fix
      prefix-development: chore
      include: scope

(optional) Configure the auto-merge probot

To merge PRs made by dependabot automatic, you may introduce probot-auto-merge. .github/auto-merge.yml will be like below:

minApprovals:
  NONE: 0
requiredLabels:
  - dependencies
updateBranch: true
mergeMethod: rebase

If we apply NONE: 0 to minApprovals configuration to merge without manual review, make sure the branch protection rule is created for the default branch, to make sure PRs will be merged only when required status checks have passed.

There is no way to configure the branch protection rule by file, so you need to use GUI at github.com like below:

Create a PAT (Personal Access Token)

semantic-release needs a GitHub token to push a commit. But when we have branch protection rules for the target branch, secrets.GITHUB_TOKEN provides not enough permission so you'll face an error like below:

error: GH006: Protected branch update failed for refs/heads/main.
error: 2 of 2 required status checks are expected.

To avoid this error, create a PAT and store it as an encrypted secret.

To keep our development environment secure, it's better to keep PAT's scope minimal as much as possible. In my case, just a public_repo scope is enough.

Configure GitHub Actions

We have a PAT so now we can configure GitHub Actions workflow!
It'll be like below:

- uses: actions/checkout@v2
        with:
          # Make sure the release step uses its own credentials.
          persist-credentials: false
      - run: |
          npm ci
          npm run all
      - name: Run semantic-release
        # This process will run `ncc`, commit files, push a Git commit, and release to GitHub and npmjs.
        run: |
          npx semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.PAT_TO_PUSH }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Or you may refer to my workflow config as a working example.

Important points are as follows:

  1. Run actions/checkout with persist-credentials: false, or git plugin will use the GitHub token generated by actions/checkout.
  2. Set the PAT created at the previous chapter to GITHUB_TOKEN when we run npx semantic-release.

Wrap up

Dependabot is really productive, even to GitHub Actions project that needs to keep the dist directory updated. semantic-release helps us not only by tagging but also by running commands to make the project ready to release.

There are several pitfalls around permission control, hope that this article helps you to avoid them. Enjoy hacking! :)

50