loading...
Cover image for GitHub Actions With Deno

GitHub Actions With Deno

craigmorten profile image Craig Morten ・6 min read

If you've written a Deno module recently, you most likely will want to ensure that you can lint, test and build it in an automated process!

If you are using a public GitHub repository to store your code then you are in luck! You can use GitHub Actions to automate all of your CI/CD needs for your GitHub project 🎉

Getting started

In your project add the following directory structure and files:

.
├── .github/
│    └── workflows/
│        └── test.yml
│
... // other folders and files

A .github directory in the root of your project containing a workflows directory, and finally a test.yml files in the workflows directory.

This test.yml file will contain all of the instructions for our GitHub Action for testing Deno.

The test file

Add the following to your test.yml file:

name: Test Deno Module

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        deno-version: [1.0.0, 1.0.1, 1.0.2]

    steps:
      - name: Git Checkout Deno Module
        uses: actions/checkout@v2
      - name: Use Deno Version ${{ matrix.deno-version }}
        uses: denolib/setup-deno@master
        with:
          deno-version: ${{ matrix.deno-version }}
      - name: Lint Deno Module
        run: deno fmt --check
      - name: Build Deno Module
        run: deno run --reload mod.ts
      - name: Test Deno Module
        run: deno test --allow-none

There's a lot going on here! So let's break it down 😄

name: Test Deno Module

First we add a name property to the test.yml file. You can change this to something relevant to your module. GitHub displays this as the name of your workflow on your repository's actions page.

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

Next we set the on property to define what triggers we would like to automatically start our action's workflow. For this example we have opted to trigger this workflow whenever a git push is made to the master branch, and also whenever there is a Pull Request that wishes to merge changes into the master branch.

If instead you wanted the action to trigger on every push no matter what branch is used, you could do something like:

on: push

Or if you wanted it to trigger on every push and pull request no matter what branch is used, you could do:

on: [push, pull_request]

You can also specify multiple branches, or a different branch to the master branch.

Finally we define the main part of our GitHub Action workflow, the jobs section:

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        deno-version: [1.0.0, 1.0.1, 1.0.2]

    // ... remainder of workflow file

Here we define the a jobs property and add a single job called test. This job is what we will be using to run our lint, test and build.

In the test object we define a runs-on property which let's GitHub know what machine OS we want to use, in this case ubuntu-latest, but there is also windows-latest, macos-latest and others to choose from.

Next we define a strategy object which allows us to define a list of Deno versions that we want this workflow to run against. Each of the subsequent steps are executed for each value in the provided array, in this example we have chosen to test against some of the version 1.x.x releases of Deno.

    steps:
      - name: Git Checkout Deno Module
        uses: actions/checkout@v2
      - name: Use Deno Version ${{ matrix.deno-version }}
        uses: denolib/setup-deno@master
        with:
          deno-version: ${{ matrix.deno-version }}
      - name: Lint Deno Module
        run: deno fmt --check
      - name: Build Deno Module
        run: deno run --reload mod.ts
      - name: Test Deno Module
        run: deno test --allow-none

Lastly we define our job's steps.

Here we define a list of steps, each with an optional name to make it clear what the step does, and then some other keys to provide instructions on what to run in that step:

  1. First we use the official actions/checkout@v2 action for performing a git checkout of our git repository onto the GitHub Action build server so we are able to test our module. This is defined using the uses parameter.

  2. Next we use the denolib/setup-deno@master action to install and configure Deno on the GitHub Action build server.

    Here we also use the additional with property to specify the variable deno-version, which the setup-deno action requires in order to know what version of Deno to install.

    Notice here we are using a special syntax ${{ matrix.deno-version }}. This is called an expression and it will evaluate to the value inside the double curly braces, in this case, the deno-version which is taken from the matrix list we provided earlier.

  3. Finally we define three more steps: one to lint, one to build and one to test our Deno module. Here we use the run property which allows us to run any command we like using the build server's shell.

    For linting we use the deno fmt --check command and flag which will check if our code is properly formatted, and exit with an error if not. If this errors, you can fix your Deno module's code formatting by running the deno fmt command (without any flags).

    For building our module we run deno run --reload mod.ts, where mod.ts is the main entypoint / starting point of our code (change the file depending on your repository setup). Here we are using the --reload flag to ensure that we fully rebuild the module and all of it's third party modules. This is to make sure that we don't accidentally rely on a cached version of the module or any third party dependencies, as this would give us a false impression of whether the module will build properly on a new module user's computer.

    For testing we use the deno test --allow-none command which will run all tests available in your repository. The --allow-none flag means that the command won't fail if your repository doesn't have any tests. If you want the test to fail if it can't find any tests, just remove the flag.

If any of the above steps fail the GitHub Action workflow will report the failure with the logs messages.

And that's it! 🎉 🎉

This workflow will work with any Deno project straight away so long as it uses the master branch as it's main branch. All you need to do is copy the test.yml file to the correct place in your repository and git push the code to GitHub.

You can then check your actions using the Actions page on your GitHub repo, and every Pull Request into the master branch and every commit to master will get a status check tick or cross depending on success or failure.

If you want to find out more about GitHub Actions, check out their Workflow Syntax Docs.

That's it peeps! Would love to hear your thoughts and how you're getting on with Deno and if you've done anything cool with GitHub Actions - drop your comments and questions below!

Posted on May 28 by:

craigmorten profile

Craig Morten

@craigmorten

26 • London • That JS Guy • JavaScript, TypeScript, React, Node, Deno, Kubernetes, Azure • I also tweet stuff

Discussion

markdown guide