Skip to content

cruel-intentions/gh-actions

Repository files navigation

Devshell GH-Actions Module

About

This is a module for Devshell that help you write your github actions yaml in Nix

If you don't know what is all about, see Devshell Files Introduction.

tl;dr: It make our config files reusable and modular

Installation

Setup configuration

Configuring new projects:

nix flake new -t github:cruel-intentions/gh-actions my-project
cd my-project
git init
nix develop --build
git add .

Configuring existing projects:

nix flake new -t github:cruel-intentions/gh-actions ./
nix develop --build
git add flake.nix flake.lock project.nix

Configuring existing Nix projects:

See Devshell-files docs

Examples

Basic

The most basic example is used by this project to tag it

# project.nix
{
  packages = ["convco"];
  # actions are disable by default, enable it (required)
  gh-actions.tag-me.enable = true;
  # there are 5 optional configurable steps
  # pre-build, build, test, deploy, post-deploy
  # only defined steps goes to yaml file
  gh-actions.tag-me.build = ''
    # tag this project on push to master
    # this is a bash script

    CURR=`convco  version`
    NEXT=`convco  version --bump`
    MAJOR=`convco version --bump --major`
    MINOR=`convco version --bump --minor`
    PATCH=`convco version --bump --patch`

    LOGS=`git log v$CURR..HEAD --format=oneline|cut -d' ' -f2`
    if echo $CURR|grep -q $NEXT; then
      echo "no reason to update tag" $CURR 
      git log v$CURR..HEAD --format=oneline
      exit 0
    fi

    NEXT=`echo $LOGS | grep -q "feat" && echo $MINOR || echo $NEXT`
    NEXT=`echo $LOGS | grep -q "!:"   && echo $MAJOR || echo $NEXT`

    git tag v$NEXT

    git push --tag
  '';
}
It generate our .github/workflows/tag-me.yaml (click to expand)
# .github/workflows/tag-me.yaml
jobs:
  tag-me:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2.4.0
        with:
          fetch-depth: 0
      - uses: cachix/install-nix-action@v15
        with:
          extra_nix_config: access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
          nix_path: channel:nixos-22.05
      - name: Build
        run: nix develop --command gh-actions-tag-me-build
"on":
  push:
    branches:
      - master

We should commit this yaml file because github can only read commited yaml files.

Complex

This is a more complex example

# examples/nodejs.nix
{
  # 'ci-cd' is the name of genereted file
  # but we are free to change it
  # In previous example we named as 'tag-it'
  gh-actions.ci-cd = {
    enable = true;
    # only run it on master and staging
    on.push.branches = ["master" "staging"];
    # only run it if JS change
    on.push.paths = ["src/**/*.js"];
    # install dependencies
    pre-build = "npm install";
    # build our site
    build = "npm run build";
    # deploy you static site
    deploy = ''
      push-to-s3 my-staging-s3-bucket staging
      push-to-s3 my-production-s3-bucket master
    '';
    # deploy needs AWS S3 credentials
    env.deploy.AWS_ACCESS_KEY_ID     = "\${{ secrets.AWS_ACCESS_KEY_ID} }}";
    env.deploy.AWS_SECRET_ACCESS_KEY = "\${{ secrets.AWS_SECRET_ACCESS_KEY }}";
    env.deploy.AWS_DEFAULT_REGION    = "\${{ secrets.AWS_DEFAULT_REGION }}";
    # create tag after deploy if master branch
    post-deploy = ''
      echo $GITHUB_REF | grep -q "master" || exit 0
      git tag v$(convco version --bump)
      git push --tag
    '';
    # We could also configure Cachix
    # https://www.cachix.org/
    cache.name = "yourCacheName";
    # git hub secret with cache token
    # cache.token-name = "CACHIX_AUTH_TOKEN"  # default value
    # git hub secret with cache signing key
    # cache.key-name   = null                 # default value
  };
  # nodejs needs to be available
  # But it could be ruby, python, rust...
  # See more 80.000 packages at https://search.nixos.org/packages
  files.cmds.nodejs-14_x = true;
  files.alias.push-to-s3 = ''
    # push to s3 bucket $1 if $2 match branch name
    echo $GITHUB_REF | grep -q $2 || exit 0
    echo deploy to $1
    aws s3 sync build s3://$1 --acl public-read --delete
  '';
}

See also