geerlingguy/ansible-role-apache

Convert from Travis CI to GitHub Actions

geerlingguy opened this issue · 11 comments

Travis kinda left open source maintainers out in the dust with their new pricing plan this week, so I'm going to transition this role (and all my others) to GitHub Actions, since I should be able to get CI done there still.

The most annoying part of this is having to release and add a GALAXY_API_KEY secret to my GitHub repositories. You can't add a secret at the profile level (only organization or repo level), so I'm going to have to write up some automation to run through all my repositories and add that secret so I can still auto-publish new tags to Galaxy.

I think I might write a script using PyGithub to loop through all my repositories and create a Secret for GitHub actions in each one using the code in this PR that adds secret support.

I created github-repo-manager, and I used it to add a GALAXY_API_KEY secret to each of the geerlingguy/ansible-role-* repositories in my account.

Yay, that wasn't super annoying. But getting all the projects updated to use actions will be :P

Merging the PR and I'm going to test tagging a new release to see if it correctly triggers a Galaxy import...

Yay, had to change the GitHub Actions workflow syntax for the on value for the Release workflow to:

'on':
  push:
    tags:
      - '*'

And now it looks like a tag triggered a build: https://github.com/geerlingguy/ansible-role-apache/actions?query=workflow%3ARelease

But the job failed :(

Also TIL if you use a folded scalar, for some reason GitHub Actions doesn't apply variable expansion correctly and join lines together. Not going to open an issue about it, but in my mind the following should be executed identically but they're not:

      - name: Trigger a new import on Galaxy.
        run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2)
      - name: Trigger a new import on Galaxy.
        run: >-
          ansible-galaxy role import
          --api-key ${{ secrets.GALAXY_API_KEY }}
          $(echo ${{ github.repository }} | cut -d/ -f1)
          $(echo ${{ github.repository }} | cut -d/ -f2)

Noting some things I'll need to do manually:

  • Update all the little CI badges on https://ansible.jeffgeerling.com
  • Adjust the on.schedule.cron value for each of the roles so they don't all fire off at exactly the same time each week.
  • Manually parse through all the .travis.yml files and adapt things like custom molecule playbooks into the GitHub Actions build matrices.
  • Delete all the .travis.yml files.
  • Manually update the CI badge links in the README files (maybe write a shell script to do it).
    [![CI](https://github.com/geerlingguy/ansible-role-ROLENAME/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-ROLENAME/actions?query=workflow%3ACI)
    
  • Figure out what to do with the Mac-related roles:
    • geerlingguy.homebrew
    • geerlingguy.mas
  • Figure out what to do with oddball roles:
    • geerlingguy.packer-debian
    • geerlingguy.packer_rhel
    • geerlingguy.raspberry-pi
  • Fix some failing builds

First step was to create a playbook that loops through a list of all my roles (available locally) and update them with the GitHub Actions workflow files:

- hosts: localhost
  gather_facts: false
  connection: local

  tasks:
    - include_tasks: role-convert-single.yml
      loop: "{{ roles }}"
      loop_control:
        loop_var: role_name

  vars:
    roles:
      - geerlingguy.adminer
      - geerlingguy.ansible
      ...

The include file:

---
- name: Ensure workflows directory exists.
  file:
    path: "{{ role_name }}/.github/workflows"
    state: directory

- name: Copy files into workflows directory.
  template:
    src: role-templates/{{ item }}.j2
    dest: "{{ role_name }}/.github/workflows/{{ item }}"
    variable_start_string: '{a'
    variable_end_string: 'a}'
  with_items:
    - ci.yml
    - release.yml

# DON'T remove the Travis CI file. Because many roles need modifications.
# DON'T edit the README.md, since that's more complicated. Urgh.

- name: Remove lint configuration from molecule.
  replace:
    path: "{{ role_name }}/molecule/default/molecule.yml"
    regexp: '^lint[^p]+'
    replace: ''
    backup: false

And then I had a ci.yml and release.yml template files, and I inserted vars like {a role_name a} since GitHub Actions syntax also uses the {{ }} convention for variable substitution, and I wanted to preserve that.

To be able to run certain molecule playbooks on only certain distros, I can use an include-only build matrix, like so:

  molecule:
    name: Molecule
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - distro: centos7
            playbook: converge.yml
          - distro: ubuntu2004
            playbook: converge.yml
          - distro: debian10
            playbook: converge.yml
          - distro: centos7
            playbook: standalone.yml

All right, I have all but my mac-related roles migrated. I'd estimate so far I'm about 12 hours of work into this, and I have probably another 20-40 to go to get all my other GitHub repositories off Travis CI, since many of them are much more customized and not uniform like my ~100 role repos.