Custom GitHub Action workflows with projen

Custom GitHub Action workflows with projen
SHARE

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