Skip to content

[RFC] Use Github Actions for StackStorm-Exchange CI and Maintenance #63

Open
@cognifloyd

Description

@cognifloyd

Current State

StackStorm-Exchange is using CircleCI for (1) pack testing and (2) updating the exchange index. Most of the CI logic is centralized in StackStorm-Exchange/ci to simplify exchange-wide CI updates. The CircleCI config (.circleci/config.yml) is a key piece of the CI infrastructure that cannot be centralized; a copy is kept in every pack on the exchange. CircleCI config can be edited by pack authors to add jobs, add docker images or steps to the standard jobs, etc. Also, the schedule for when weekly pack tests occur (Saturday/Sunday) is in the pack-local circle config.

All other administrative tasks across the exchange require manual intervention by oneor more of the project maintainers. There are several versions of shared scripts that the maintainers pass around (in StackStorm-Exchange/ci, StackStorm-Exchange/exchange-tools, and StackStorm-Exchange/exchange-misc) to handle these administrative tasks. Other updates might be handled by ad-hoc scripting.

aside: this proposal has nothing to do with recent discussion around dropping python2.7 testing on the exchange. It is about optimizing our CI infrastructure for the Exchange.

Goals

  1. Automate as many of the manual administrative tasks as possible. Wherever possible, prefer solutions that happen on-push, or on-merge, or other no-touch triggers.
  2. Allow individual packs to add additional custom testing workflows.
  3. Allow individual packs to customize the standard workflows/jobs (eg add docker images, add system deps, setup custom testing harnesses, download extra repos needed for tests, ...)
  4. Given that customization, minimize the effort required to:
    • adjust the weekly test schedule for multiple packs (Saturday/Sunday/etc).
    • do exchange-wide pack updates for our standard pack CI workflows: pack tests, index update. An autonomous solution that updates pack CI config in all repos once a "master" copy of the config gets merged would be ideal.

Proposal

I recommend we move the Exchange's CI workflows from Circle CI to Github Actions. This includes writing a variety of new workflows to automate as many administrative tasks as possible.

For at least one of those workflows, use a tool that allows us to merge yaml files so that the standard CI jobs can be extended in ways that do not prevent automated updates of the file. Some form of centralized "variables" could be used to define, for example, the test schedule for various packs.

Other CI provider options

Many projects (including StackStorm) have been abandoning Travis CI for many reasons, so that is not a viable option for the exchange.

Circle CI has served us well. Circle CI uses a single config file for all of the CI workflows. However, a single config file for all CI makes it more difficult to both allow customization, and simplify exchange-wide CI updates.

The first bullet under Goal 4 provides another reason not to use CircleCI. The schedule is another potential merge conflict that makes doing exchange-wide pack updates difficult.

Why Github Actions (GHA)?

Looking at the goals listed above, writing workflows for 1 could probably be accomplished with any CI provider. But GHA might have a slight edge as it is much closer to the Github API, and many community-written-actions alreadfy implement some of the workflows, or steps in those workflows, that we'll need.

Goal 2 is the clearest winner with moving to GHA. This comes free with GHA, as each workflow is a separate file in the repo. So, any custom workflow files will be safe from exchange-wide updates to the standard workflows.

The tension between goals 3 and 4 require additional effort. But, with additional tooling we can define extension points in our standard CI pack test workflow(s) so that it can be updated by both pack authors and by exchange-wide CI updates. There are few yaml templating/merging options available. At least one of them should be runnable within github workflows.

Proposed new workflows

For the first bullet under goal 4, adjust weekly test schedule, we could have a centralized file that assigns packs to CI slots (currently Saturday or Sunday). Then, when that file gets updated (eg w/ a new pack), that can trigger a workflow that pushes out the assigned schedule to packs that need an update.

For the second bullet under goal 4, exchange-wide pack CI updates, we could have a central template file for the standard CI workflow config. When a PR that updates that template is merged, that would trigger a CI workflow that goes through all the exchange's packs, regenerates the affected standard workflows. That regeneration would take into account the schedule, and it would merge any customizations into the standard workflow.

Also, when the files that provide the customizations are updated in one of the packs, that should trigger regenerating the affected workflow file as well.

YAML merge tool options

Here are two options:

  1. modulesync/pdk
  2. gflows

I would prefer gflows, assuming it works well for our use cases.

modulesync and/or pdk

Written in ruby.

Quoting @nmaludy: https://stackstorm-community.slack.com/archives/CSBELJ78A/p1612183089198000

The way the Puppet community handles problems like this is to use a tool called modulesync and/or pdk (they perform the exact same).

Basically they work by having a "template" directory structure with a bunch of ERB (think Jinja) templates. Those templates get rendered based on a config file .sync.yml customizations that can be unique per-repo (pack in our case).

This way if one pack needs to modify the CircleCI config by adding jobs or service containers, steps, whatever... It is very easy to do so and those differences from the "normal" are documented and able to be maintained, even when the template config changes.

These tools also provide a way to mass-render and make PRs across a huge number of repos. Basically, for each repo, make branch, run modulesync, push branch, make PR.

The other difference here is that these tools push the CI scripts to each repo, rather than having a central CI repo that everyone has to clone. Bonus points on this is that each repo has its own Gemfile.lock (think requirements.txt ) that can be used for correctly hashing CI requirements for a repo. I know we've had the problem in the past where a dependency in some cloned repo was causing problems and even though we updated it, the CI cache wasn't changed because we weren't properly aggregating our requirements.txt.

https://github.com/voxpupuli/modulesync
https://puppet.com/docs/pdk/1.x/pdk_reference.html

gflows

Written in go.

gflows is a tool (and a github action) that uses jsonnet or ytt to template github workflow files.

Being a golang static-binary, it can be simply downloaded/run both in CI, and locally on pack authors' machines. Thus, the pack author will not have to set up any special environment (ruby, python, or otherwise) to regenerate any customized standard workflow file locally when authoring the pack.

https://github.com/jbrunton/gflows

Alternatives

One approach to adding customization within the CircleCI config is to one or more bash scripts throughout the standard workflows so pack authors can add their customization there. This is the approach taken by: StackStorm-Exchange/ci#101

This satisfies only part of goal 3. Other changes, like adding docker images or adding workflows, would also need a yaml merge solution.

Request for Comment

Does anyone have any additional pros/cons or opinions to add about:

  1. moving StackStorm-Exchange from CircleCI to Github Actions
  2. automating exchange maintenance with new workflows
  3. gflows vs modulesync
  4. using gflows to allow explicit customization of the pack CI

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions