Git Product home page Git Product logo

gha-puppet's Introduction

Puppet Github Actions

These are reusable workflows to run Puppet tests within Github Actions.

They are heavily focused on the workflow that Vox Pupuli uses, which rely on rake tasks from puppetlabs_spec_helper. The tasks executed are:

  • validate
  • lint
  • check
  • rubocop if enabled (default)
  • parallel_spec in a matrix for every supported Puppet version

For more information, see GitHub's workflow reuse documentation.

Vox Pupuli uses these workflows to test modules. You can reuse them for your own modules (as documented in the next section). But they can also be configured to test modules that are vendored in a controlrepository or a monorepository. See Working with a subdirectory for details.

Gemfile integration examples

Below is an annotated example Gemfile which should provide a working environment. It's the minimum needed.

source 'https://rubygems.org'

# The development group is intended for developer tooling. CI will never install this.
group :development do
end

# The test group is used for static validations and unit tests in gha-puppet's
# basic and beaker gha-puppet workflows.
group :test do
  # Require the latest Puppet by default unless a specific version was requested
  # CI will typically set it to '~> 7.0' to get 7.x
  gem 'puppet', ENV.fetch('PUPPET_GEM_VERSION', '>= 0'), require: false
  # Needed to build the test matrix based on metadata
  gem 'puppet_metadata', '~> 3.4', require: false
  # Needed for the rake tasks
  gem 'puppetlabs_spec_helper', '>= 2.16.0', '< 7', require: false
  # Rubocop versions are also specific so it's recommended
  # to be precise. Can be turned off via a parameter
  gem 'rubocop', require: false
end

# The system_tests group is used in gha-puppet's beaker workflow.
group :system_tests do
  gem 'beaker', require: false
  gem 'beaker-docker', require: false
  gem 'beaker-rspec', '>= 8.0', require: false
end

# The release group is used in gha-puppet's release workflow
group :release do
  gem 'puppet-blacksmith', '>= 6', '< 8', require: false
end

It is recommended to use voxpupuli-test, voxpupuli-acceptance, and voxpupuli-release to manage the dependencies.

source 'https://rubygems.org'

# The development group is intended for developer tooling. CI will never install this.
group :development do
end

# The test group is used for static validations and unit tests in gha-puppet's
# basic and beaker gha-puppet workflows.
group :test do
  # Require the latest Puppet by default unless a specific version was requested
  # CI will typically set it to '~> 7.0' to get 7.x
  gem 'puppet', ENV.fetch('PUPPET_GEM_VERSION', '>= 0'), require: false
  # Needed to build the test matrix based on metadata
  gem 'puppet_metadata', '~> 3.2',  require: false
  # metagem that pulls in all further requirements
  gem 'voxpupuli-test', '~> 7.0', require: false
end

# The system_tests group is used in gha-puppet's beaker workflow.
group :system_tests do
  gem 'voxpupuli-acceptance', '~> 2.1', require: false
end

# The release group is used in gha-puppet's release workflow
group :release do
  gem 'voxpupuli-release', '~> 3.0', '>= 3.0.1'
end

Rakefile integration example

This is the most minimal Rakefile you can have and still use all the shared actions.

begin
  require 'puppetlabs_spec_helper/rake_tasks'
rescue LoadError
  # Allowed to fail, only needed in test
end

begin
  require 'beaker-rspec/rake_task'
rescue LoadError
  # Allowed to fail, only needed in acceptance
end

begin
  require 'puppet_blacksmith/rake_tasks'
rescue LoadError
  # Allowed to fail, only needed in release
end

Calling test workflows

It is recommended to create a single workflow for all Puppet tests and name it .github/workflows/puppet.yml.

Basic tests

There is a workflow defined that runs the basic tests. It does not run acceptance tests.

name: CI

on: pull_request

concurrency:
  group: ${{ github.ref_name }}
  cancel-in-progress: true

jobs:
  puppet:
    name: Puppet
    uses: voxpupuli/gha-puppet/.github/workflows/basic.yml@v1

To disable Rubocop, modify the job:

jobs:
  puppet:
    name: Puppet
    uses: voxpupuli/gha-puppet/.github/workflows/basic.yml@v1
    with:
      rubocop: false

Beaker tests

For modules using beaker for acceptance testing there is a workflow which also includes the basic tests. Like basic tests, it accepts a rubocop parameter.

name: CI

on: pull_request

concurrency:
  group: ${{ github.ref_name }}
  cancel-in-progress: true

jobs:
  puppet:
    name: Puppet
    uses: voxpupuli/gha-puppet/.github/workflows/beaker.yml@v1

Install additional packages

The basic and the beaker workflow support the additional_packages input string. You can use that to install additional packages. The String is passed to sudo apt-get install -y

jobs:
  puppet:
    name: Puppet
    uses: voxpupuli/gha-puppet/.github/workflows/basic.yml@v1
    with:
      additional_packages: 'libaugeas-dev augeas-tools'

Calling the release workflow

The release workflow relies on puppet-blacksmith and in particular the module:push rake task.

There is one input:

  • allowed_owner - The workflow only runs if the owner matches. This prevents forks from attempting to release.

There are multiple secrets (GitHub's secrets documentation):

It is recommended to create a workflow .github/workflows/release.yml.

name: Release

on:
  push:
    tags:
      - '*'

jobs:
  deploy:
    name: Deploy
    uses: voxpupuli/gha-puppet/.github/workflows/release.yml@v1
    with:
      allowed_owner: MY_GITHUB_USERNAME
    secrets:
      username: ${{ secrets.PUPPET_FORGE_USERNAME }}
      api_key: ${{ secrets.PUPPET_FORGE_API_KEY }}

Working with a subdirectory

Assume you've a controlrepository or a monorepository:

.
├── bin
│   └── config_script.sh
├── data
│   └── nodes
├── environment.conf
├── hiera.yaml
├── LICENSE
├── manifests
│   └── site.pp
├── Puppetfile
├── README.md
└── site
    └── profiles
        ├── files
        ├── Gemfile
        ├── manifests
        ├── metadata.json
        ├── Rakefile
        ├── REFERENCE.md
        └── templates

You can use our workflow for the vendored module (in this example profiles) as well. They all support a working-directory input that you can set to the vendored module:

name: CI

on: pull_request

concurrency:
  group: ${{ github.ref_name }}
  cancel-in-progress: true

jobs:
  puppet:
    name: Puppet
    uses: voxpupuli/gha-puppet/.github/workflows/beaker.yml@v1
    working-directory: ./site/profiles

gha-puppet's People

Contributors

alexjfisher avatar bastelfreak avatar bschonec avatar dependabot[bot] avatar ekohl avatar evgeni avatar jay7x avatar smortex avatar traylenator avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gha-puppet's Issues

GitHub Actions fails with "fatal: ls-files -i must be used with either -o or -c"

Hi,

It seems that voxpupuli/gha-puppet/.github/workflows/basic.yml@v1 fails now with an error related to Git syntax errors:

fatal: ls-files -i must be used with either -o or -c

This has been reported by other projects and seems related to a Git version that breaks backwards compatibility. This issue seems to affect Ubuntu 20.04 and 22.04 images. Here's another report of what seems to be the same issue:

The relevant raw logs from GitHub Action here:

2023-01-23T08:42:14.9307855Z Requested labels: ubuntu-latest
2023-01-23T08:42:14.9307894Z Job defined at: voxpupuli/gha-puppet/.github/workflows/basic.yml@refs/heads/v1
2023-01-23T08:42:14.9308042Z Reusable workflow chain:
2023-01-23T08:42:14.9308082Z Puppet-Finland/puppet-ipa/.github/workflows/ci.yml@refs/pull/51/merge (a6b9e583c969e253f014370a2d6b01607aacfb6a)
2023-01-23T08:42:14.9308123Z -> voxpupuli/gha-puppet/.github/workflows/basic.yml@refs/heads/v1 (a8fea30a9fcf14fd4cc9071c839e5a55d5dbab83)
2023-01-23T08:42:14.9308143Z Waiting for a runner to pick up this job...
2023-01-23T08:42:15.3069344Z Job is waiting for a hosted runner to come online.
2023-01-23T08:42:20.0951290Z Job is about to start running on the hosted runner: Hosted Agent (hosted)
2023-01-23T08:42:22.2513455Z Current runner version: '2.300.2'
2023-01-23T08:42:22.2547523Z ##[group]Operating System
2023-01-23T08:42:22.2548413Z Ubuntu
2023-01-23T08:42:22.2548716Z 22.04.1
2023-01-23T08:42:22.2548996Z LTS
2023-01-23T08:42:22.2549248Z ##[endgroup]
2023-01-23T08:42:22.2549569Z ##[group]Runner Image
2023-01-23T08:42:22.2549971Z Image: ubuntu-22.04
2023-01-23T08:42:22.2550251Z Version: 20230118.2
2023-01-23T08:42:22.2550763Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20230118.2/images/linux/Ubuntu2204-Readme.md
2023-01-23T08:42:22.2551397Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20230118.2
2023-01-23T08:42:22.2551804Z ##[endgroup]
--- snip ---
2023-01-23T08:42:22.2562884Z Prepare workflow directory
2023-01-23T08:42:22.3750447Z Prepare all required actions
2023-01-23T08:42:22.3931872Z Getting action download info
2023-01-23T08:42:22.6214970Z Download action repository 'actions/checkout@v3' (SHA:ac593985615ec2ede58e132d2e21d2b1cbd6127c)
2023-01-23T08:42:23.0219206Z Download action repository 'ruby/setup-ruby@v1' (SHA:ee26e27437bde475b19a6bf8cb73c9fa658876a2)
2023-01-23T08:42:23.3344054Z Uses: voxpupuli/gha-puppet/.github/workflows/basic.yml
--- snip ---
2023-01-23T08:42:35.9539098Z [36;1mbundle exec rake validate lint check[0m
2023-01-23T08:42:35.9592809Z shell: /usr/bin/bash -e {0}
2023-01-23T08:42:35.9593038Z env:
2023-01-23T08:42:35.9593325Z   BUNDLE_WITHOUT: development:system_tests:release
2023-01-23T08:42:35.9593701Z ##[endgroup]
2023-01-23T08:42:37.0076470Z ruby -c lib/facter/ipa_server_version.rb
2023-01-23T08:42:37.0117439Z Syntax OK
2023-01-23T08:42:37.0126079Z ---> syntax:manifests
2023-01-23T08:42:37.3167538Z ---> syntax:templates
2023-01-23T08:42:37.3600457Z ---> syntax:hiera:yaml
2023-01-23T08:42:37.9234627Z fatal: ls-files -i must be used with either -o or -c

Find a convention for specifying Puppet's version to Gemfile

Vox Pupuli uses https://github.com/voxpupuli/modulesync_config/blob/a87ca50493f5b1ac09956fd7f8c226cf6fc3165f/moduleroot/Gemfile.erb#L38-L39 or:

puppetversion = ENV['PUPPET_VERSION'] || '<%= @configs['puppet_version'] %>'
gem 'puppet', puppetversion, :require => false, :groups => [:test]

The Foreman uses puppetversion = ENV['PUPPET_VERSION'] || '<%= @configs['puppet_version'] %>'
gem 'puppet', puppetversion, :require => false, :groups => [:test] or:

gem 'puppet', ENV.key?('PUPPET_VERSION') ? "~> #{ENV['PUPPET_VERSION']}" : '>= 5.5', groups: ['development', 'test']

pdk-templates uses https://github.com/puppetlabs/pdk-templates/blob/b851eaa1db21ee695c07da1a9594a86403bfcc18/moduleroot/Gemfile.erb#L103-L109 or (summarized for readability):

def location_for(place_or_version, fake_version = nil)
  git_url_regex = %r{\A(?<url>(https?|git)[:@][^#]*)(#(?<branch>.*))?}
  file_url_regex = %r{\Afile:\/\/(?<path>.*)}

  if place_or_version && (git_url = place_or_version.match(git_url_regex))
    [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact
  elsif place_or_version && (file_url = place_or_version.match(file_url_regex))
    ['>= 0', { path: File.expand_path(file_url[:path]), require: false }]
  else
    [place_or_version, { require: false }]
  end
end

puppet_version = ENV['PUPPET_GEM_VERSION']
gem_params = location_for(puppet_version)
gem 'puppet', *gem_params

So none of these really is the same:

  • VP and Foreman use PUPPET_VERSION as the environment variable but PDK uses PUPPET_GEM_VERSION
  • VP and PDK use the full specifier while Foreman forces ~>

If these workflows are to be used by all, it would be good to align on a single convention.

PUPPET_GEM_VERSION does have the benefit that it doesn't overlap with PUPPET_VERSION which is also used in beaker-puppet_install_helper (https://github.com/puppetlabs/beaker-puppet_install_helper/blob/41c355b1f83fde562dd5bd6961e2e4eb8b81421c/lib/beaker/puppet_install_helper.rb#L128) which, while archived, is still used by Vox Pupuli and Foreman in their Beaker setups.

Document `Gemfile` expectations

The workflow uses environment variables to set the Puppet version (see #3 as well), but it also has some groups.

It also depends on puppetlabs_spec_helper, which is mentioned but not that it must be in Gemfile.

It also relies on https://github.com/voxpupuli/puppet_metadata to be present since it needs to parse metadata.json to generate the matrix.

- name: Setup Test Matrix
id: get-outputs
run: bundle exec metadata2gha --use-fqdn

Perhaps the matrix generation should also be pushed in puppetlabs_spec_helper as a rake task, since that's generally the interface anyway. If puppetlabs_spec_helper has the right dependencies, it reduces the need to track things in Gemfile.

Support beaker facts in the test matrix

# TODO: beaker_fact_matrix input

It's possible to set a fact via environment variables. This is used in theforeman/puppet-pulpcore to run the entire test suite on multiple supported versions.

It would be great if this was also supported in gha-puppet.

I started with voxpupuli/puppet_metadata#35 which at least pushes the name generation into the gem. That gem already generates the matrix so this opens the path to generating a bigger matrix. Then it just needs a good way to specify the inputs and map it.

Github action "basic.yml" fails because Gem parallel_spec is not sepcified/installed.

I'm trying to use the gha-puppet reusable workflows for the first time and the parallel_tests are failing. I can only assume this is because the parallel_spec Gem is not installed.

I'm very green at this so I don't know where the solutions is. The output error when I have a completely generic project is:

Run ruby/setup-ruby@v1
Modifying PATH
Downloading Ruby
Extracting  Ruby
Print Ruby version
Installing Bundler
> bundle install
/opt/hostedtoolcache/Ruby/3.0.5/x64/bin/bundle config --local path /home/runner/work/junk/junk/vendor/bundle
/opt/hostedtoolcache/Ruby/3.0.5/x64/bin/bundle lock
Fetching gem metadata from https://rubygems.org/.......
Could not find gem 'parallel_spec_standalone' in rubygems repository
https://rubygems.org/ or installed locally.
Error: The process '/opt/hostedtoolcache/Ruby/3.0.5/x64/bin/bundle' failed with exit code 7

I added "gem 'parallel_tests'" to my Gemfile and it seemed to make things better.

Github action fails "Setup ruby" when using Gemfile from README.md

I created a completely blank puppet module, copied over Gemfile and Rakefile verbatim, created the puppet.yml Github action file and upon creating a pull request, the Github action fails at "Setup Ruby". I believe this is because the Gemfile doesn't have a pointer to get the gems installed. I added the following to the top of the Gemfile:

source ENV['GEM_SOURCE'] || 'https://rubygems.org'
re-ran the action and the "Setup Ruby" job passed.

The Gemfile at voxpupuli/puppet-chrony implies that the GEM_SOURCE needs to be set.

Rename beaker.yml?

The job does more than only beaker tests, should the filename reflect that?

Upload puppet-lint output in SARIF format

You can set up puppet-lint and GHA to upload in SARIF format. The explore workflows suggests the following workflow:

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# Puppet Lint tests Puppet code against the recommended Puppet language style guide.
# https://puppet.com/docs/puppet/7/style_guide.html
# Puppet Lint validates only code style; it does not validate syntax.
# To test syntax, use Puppet's puppet parser validate command.
# More details at https://github.com/puppetlabs/puppet-lint/

name: puppet-lint

on:
  push:
    branches: [ "master" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "master" ]
  schedule:
    - cron: '41 13 * * 2'

permissions:
  contents: read

jobs:
  puppet-lint:
    name: Run puppet-lint scanning
    runs-on: ubuntu-latest
    permissions:
      contents: read # for checkout to fetch code
      security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
      actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Ruby
        uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
        with:
          ruby-version: 2.7
          bundler-cache: true

      - name: Install puppet-lint
        run: gem install puppet-lint

      - name: Run puppet-lint
        run: puppet-lint . --sarif > puppet-lint-results.sarif
        continue-on-error: true

      - name: Upload analysis results to GitHub
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: puppet-lint-results.sarif
          wait-for-processing: true

Obviously we only care about the last 2 steps, but the permissions are also useful.

This may be nicer than annotations because it also shows up in code scans when run on the cron schedule.

Perhaps this is something that belongs in voxpupuli-test, perhaps somewhere in between.

`--pidfile-workaround CentOS` removes centos 8 from output.

[acceptance] ~/github/puppet-alternatives $ be metadata2gha | grep beaker_setfiles
::set-output name=beaker_setfiles::[{"name":"Debian 10","value":"debian10-64"},{"name":"Debian 11","value":"debian11-64"},{"name":"Ubuntu 18.04","value":"ubuntu1804-64"},{"name":"Ubuntu 20.04","value":"ubuntu2004-64"},{"name":"CentOS 7","value":"centos7-64"},{"name":"CentOS 8","value":"centos8-64"}]
[acceptance] ~/github/puppet-alternatives $ be metadata2gha --pidfile-workaround false | grep beaker_setfiles
::set-output name=beaker_setfiles::[{"name":"Debian 10","value":"debian10-64"},{"name":"Debian 11","value":"debian11-64"},{"name":"Ubuntu 18.04","value":"ubuntu1804-64"},{"name":"Ubuntu 20.04","value":"ubuntu2004-64"},{"name":"CentOS 7","value":"centos7-64"},{"name":"CentOS 8","value":"centos8-64"}]
[acceptance] ~/github/puppet-alternatives $ be metadata2gha --pidfile-workaround CentOS | grep beaker_setfiles
::set-output name=beaker_setfiles::[{"name":"Debian 10","value":"debian10-64"},{"name":"Debian 11","value":"debian11-64"},{"name":"Ubuntu 18.04","value":"ubuntu1804-64"},{"name":"Ubuntu 20.04","value":"ubuntu2004-64"},{"name":"CentOS 7","value":"centos7-64{image=centos:7.6.1810}"}]

This was discovered while working on voxpupuli/puppet-alternatives#126

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.