Custom GitHub Action workflows with projen

This article will show you how to add custom GitHub Actions workflows with Projen

Custom GitHub Action workflows with projen

I use projen for almost all of my projects because it allows me to not worry about all of the very necessary but tedious parts of a project - .gitignore, .eslintrc.json, GitHub Actions workflows, etc. However, I often find myself having both a front end and back end in the same repository. While projen and GitHub Actions will automatically take care of upgrading dependencies in my main folder, I also want it to take care of dependencies in other parts of my project.

Schedule

For the main folder dependencies, once a day upgrades is very aggressive. We can adjust that in our .projenrc.js file to weekly:

const { UpgradeDependenciesSchedule } = require("projen/lib/javascript");
 
const project = new awscdk.AwsCdkTypeScriptApp({
  ...projectConfig,
  depsUpgradeOptions: {
    ignoreProjen: false,
    workflowOptions: {
      labels: ["auto-approve", "auto-merge"],
      schedule: UpgradeDependenciesSchedule.WEEKLY,
    },
  },
});

This pushes our upgrade workflow out to once a week:

name: upgrade
on:
  workflow_dispatch: {}
  schedule:
    - cron: 0 0 * * 1

Additional Actions

To add an action, we will once again edit our .projenrc.js file. This time we will add a workflow.

const { JobPermission } = require("projen/lib/github/workflows-model");
 
const upgradeSite = project.github.addWorkflow("upgrade-site");
upgradeSite.on({ schedule: [{ cron: "0 0 * * 1" }], workflowDispatch: {} });

This will create a new workflow on the same schedule as the existing upgrade workflow.

Next, we will add a job that will:

  • Install dependencies via yarn
  • Upgrade dependencies
  • Create a Pull Request
upgradeSite.addJobs({
  upgradeSite: {
    runsOn: ["ubuntu-latest"],
    name: "upgrade-site",
    permissions: {
      actions: JobPermission.WRITE,
      contents: JobPermission.READ,
      idToken: JobPermission.WRITE,
    },
    steps: [
      { uses: "actions/checkout@v3" },
      {
        name: "Setup Node.js",
        uses: "actions/setup-node@v3",
        with: {
          "node-version": "16",
        },
      },
      {
        run: "yarn install --check-files --frozen-lockfile",
        workingDirectory: "site",
      },
      { run: "yarn upgrade", workingDirectory: "site" },
      {
        name: "Create Pull Request",
        uses: "peter-evans/create-pull-request@v4",
        with: {
          token: "${{ secrets." + AUTOMATION_TOKEN + " }}",
          "commit-message": "chore: upgrade site",
          branch: "auto/projen-upgrade",
          title: "chore: upgrade site",
          body: "This PR upgrades site",
          labels: "auto-merge, auto-approve",
          author: "github-actions <github-actions@github.com>",
          committer: "github-actions <github-actions@github.com>",
          signoff: true,
        },
      },
    ],
  },
});

Adjust the workingDirectory as needed for any directory that has dependencies that can be upgraded.

Result

Now, we will have a weekly GitHub Actions workflow that will upgrade dependencies for both our main folder, as well as a subfolder of our choosing. This can be used to help keep Dependabot alerts to a minimum by keeping up with security updates.

name: upgrade-site
on:
  schedule:
    - cron: 0 5 * * 1
  workflow_dispatch: {}
jobs:
  upgradeSite:
    name: upgrade-site
    runs-on: ubuntu-latest
    permissions:
      actions: write
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "16"
      - run: yarn install --check-files --frozen-lockfile
        working-directory: site
      - run: yarn upgrade
        working-directory: site
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v4
        with:
          token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
          commit-message: "chore: upgrade site"
          branch: auto/projen-upgrade
          title: "chore: upgrade site"
          body: This PR upgrades site
          labels: auto-merge, auto-approve
          author: github-actions <github-actions@github.com>
          committer: github-actions <github-actions@github.com>
          signoff: true