Setup Continuous Integration using GitHub Actions

:mag: Overview

To build a robust extension for Discourse, it can be wise to include Continuous Integration (CI) into your plugin or theme-component. This will help to detect errors early on and lessen the chances of bugs in your code.

Setting up a CI workflow using GitHub Actions to automate builds and testing is an approach the Discourse team uses on all our components, and we recommend you do the same.

:gear: Setting it up

To add automated workflows for GitHub actions to detect, you need to create a .github/workflows folder in the root directory of your repository.

Inside the workflows folder you can define a set of automations that GitHub actions will need to run. For instance, these could be .yml files for linting and tests.

We’ve created template workflows for both plugins and theme components which you can make use of. These connect to our ‘reusable workflow’ definitions here.

In the template’s skeleton repository, on GitHub you can click the Use this template button to create a plugin/theme component repository based on the template.

Alternatively, if you already have a project you’d like to add the workflows to, simply copy the relevant workflow into your repository’s .github/workflows/ folder:

:electric_plug: Plugins: discourse-plugin.yml

:jigsaw: Themes and Theme Components: discourse-theme.yml

:point_up: These templates are locked to a specific major version of our reusable workflows. Small improvements we make to the workflows will automatically take effect in your theme/plugin. For breaking changes (e.g. introducing a new linter), we will bump the major version of the reusable workflows, and you will need to update your workflow to point to the new version

:tada: Voila! You’re all setup! Simply, create a commit or a PR to your repository and GitHub actions will auto-detect the workflows and begin running the jobs.

GitHub actions will show a breakdown of each test and after running it will indicate either a :white_check_mark: or :x: depending on if the test passed or failed.

If a test failed, clicking on the details will give you a some information on what failed which may give you clues on what’s wrong with your code and what needs to be fixed.

See example

:white_check_mark: Add your own tests

For plugin and components tests to work effectively, its important that you write tests for your plugin or theme component.

For details on how to write front-end tests with EmberJS see:

For more details on writing test RSpec tests with Rails see:

:bulb: Examples

For your benefit, we’ve picked out a couple examples of plugins and theme components that have some robust testing integrated:


This document is version controlled - suggest changes on github.

14 Likes

You might mention GitHub - discourse/discourse-theme-skeleton: Template for Discourse themes explicitly and note that you should watch it to take note of changes in those files.

4 Likes

Hopefully the reusable workflows can get merged, making this part less relevant as new repositories made from the template will use the workflows from the template repository directly.

2 Likes

Thanks @pfaffman and @Simon_Manning, good points. I’ve updated the OP accordingly.

4 Likes

I’ve updated the OP to include instructions for using our new ‘reusable workflows’. Minor tweaks we make to the workflow definitions can now be automatically applied to your themes/plugins without any manual work.

3 Likes

Do I need to do anything special to have a plugin tested against latest tests-passed and stable?

1 Like

The plugin skeleton workflow uses the following, which I think will test against the default branch, so main. The reusable workflow has an optional core_ref input and as far as I can tell, without it the discourse/discourse repository’s default branch will get checked out.

jobs:
  ci:
    uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1

I can’t say whether that actually limits it to testing against main or not but if it does, you could add a matrix strategy to run once for each ref you want to test against.

jobs:
  ci:
    strategy:
      matrix:
        target: [tests-passed, stable]
    uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1
    with:
      core_ref: ${{ matrix.target }}
3 Likes

Yup that should do it. Or you can just write the two jobs out manually without using a matrix:

name: Discourse Plugin

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  ci:
    uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1

  ci-stable:
    uses: discourse/.github/.github/workflows/discourse-plugin.yml@v1
    with:
      core_ref: stable

Worth noting though: these jobs won’t check .discourse-compatiblity. So this is only worth doing on plugins that don’t use that file, and need to be compatible with both main and stable simultaneously.

For all of CDCK’s public themes/plugins, we add an entry to discourse-compatibility to ‘freeze’ them at every stable release. Then we don’t need to worry about stable compatibility while developing them.

4 Likes

Thanks to both of you.

Yeah that’s probably the most straightforward approach. The only downside is it potentially holds back features (and new bug fixes)

2 Likes