diff --git a/.github/actions/acceptance-test/action.rake b/.github/actions/acceptance-test/action.rake new file mode 100644 index 0000000..417efb9 --- /dev/null +++ b/.github/actions/acceptance-test/action.rake @@ -0,0 +1,26 @@ +# output task execution +unless Rake.application.options.trace + setup = ->(task, *_args) do + puts "\e[36m==> rake #{task}\e[0m" + end + + task :log_hooker do + Rake::Task.tasks.reject { |t| t.to_s == 'log_hooker' }.each do |a_task| + a_task.actions.prepend(setup) + end + end + Rake.application.top_level_tasks.prepend(:log_hooker) +end + +# serial acceptance task +namespace :litmus do + desc "Run tests against all nodes in the litmus inventory\n(defaults: tag=nil)" + task :acceptance, [:tag] do |_task, args| + args.with_defaults(tag: nil) + + Rake::Task.tasks.select { |t| t.to_s =~ %r{^litmus:acceptance:(?!(localhost|parallel)$)} }.each do |litmus_task| + puts "Running task #{litmus_task}" + litmus_task.invoke(*args) + end + end +end diff --git a/.github/actions/acceptance-test/action.yml b/.github/actions/acceptance-test/action.yml new file mode 100644 index 0000000..2c2d4f5 --- /dev/null +++ b/.github/actions/acceptance-test/action.yml @@ -0,0 +1,133 @@ +--- +name: "Acceptance Test" + +inputs: + docker_image: + required: true + type: string + repo: + required: true + type: string + ref: + type: string + provision_task: + required: true + default: "docker" + type: string + provision_module: + description: 'override provision module in .fixtures.yml' + type: string + puppet_agent_module: + description: 'override puppet_agent module in .fixtures.yml' + type: string + ruby_version: + required: true + default: "2.7" + type: string + path: + description: 'working directory (default ${github.workspace}/acceptance_test)' + type: string + +runs: + using: "composite" + steps: + - id: vars + shell: bash + run: | + echo "working-directory=${{ inputs.path != '' && inputs.path || format('{0}/acceptance_test', github.workspace) }}" >> "${GITHUB_OUTPUT}" + + - name: Checkout Module (Act) + if: github.actor == 'nektos/act' + shell: bash + run: git clone https://github.com/${{ inputs.repo }} ${{ steps.vars.outputs.working-directory }} + + - name: Checkout Module (Github) + if: github.actor != 'nektos/act' + uses: actions/checkout@v4 + with: + repository: ${{ inputs.repo }} + ref: ${{ inputs.ref }} + path: ${{ steps.vars.outputs.working-directory }} + + - name: Setup Ruby + uses: "ruby/setup-ruby@v1" + with: + ruby-version: ${{ inputs.ruby_version }} + bundler-cache: true + working-directory: ${{ steps.vars.outputs.working-directory }} + + - name: Custom fixtures + if: (inputs.provision_module != '' || inputs.puppet_agent_module != '') + working-directory: ${{ steps.vars.outputs.working-directory }} + shell: ruby {0} + run: | + require 'yaml' + require 'json' + + input = {} + input['provision'] = < + ${{ inputs.image && format('image={0}', inputs.image) || '' }} + ${{ inputs.repo && format('repo={0}', inputs.repo) || '' }} + ${{ inputs.ref && format('ref={0}', inputs.ref) || '' }} + +on: + workflow_dispatch: + inputs: + image: + required: true + description: Litmus image:tag + type: string + default: "debian:10" + repo: + description: repo of module to acceptance test + type: string + default: "puppetlabs/puppetlabs-stdlib" + ref: + description: module git ref (optional) + type: string + provision_task: + description: provision task + type: choice + default: docker + options: + - docker + - docker_exp + latest_modules: + description: patch module fixtures with latest Puppet Litmus required modules + type: boolean + default: true + provision_module: + description: provision module overrides (JSON Hash) + type: string + puppet_agent_module: + description: puppet_agent module overrides (JSON Hash) + type: string + +env: + REGISTRY: ${{ vars.DOCKER_REGISTRY != '' && vars.DOCKER_REGISTRY || 'ghcr.io' }} + REPOSITORY: ${{ vars.DOCKER_REPOSITORY != '' && vars.DOCKER_REPOSITORY || github.repository }} + BOLT_GEM: 1 + +jobs: + acceptance: + runs-on: ubuntu-latest + steps: + - name: Setup Vars + id: vars + run: | + if [[ "${{ inputs.latest_modules }}" != "false" ]] ; then + echo 'provision_module="https://github.com/puppetlabs/provision.git"' >> "${GITHUB_OUTPUT}" + echo 'puppet_agent_module="https://github.com/puppetlabs/puppetlabs-puppet_agent.git"' >> "${GITHUB_OUTPUT}" + fi + if [[ -n "${{ inputs.provision_module }}" ]] ; then + echo 'provision_module=${{ inputs.provision_module }}' >> "${GITHUB_OUTPUT}" + fi + if [[ -n "${{ inputs.puppet_agent_module }}" ]] ; then + echo 'puppet_agent_module=${{ inputs.puppet_agent_module }}' >> "${GITHUB_OUTPUT}" + fi + + - name: Checkout + uses: actions/checkout@v4 + + - name: Test + uses: ./.github/actions/acceptance-test + with: + docker_image: ${{ env.REGISTRY }}/${{ env.REPOSITORY }}/${{ inputs.image }} + repo: ${{ inputs.repo }} + ref: ${{ inputs.ref }} + provision_task: ${{ inputs.provision_task }} + provision_module: ${{ steps.vars.outputs.provision_module }} + puppet_agent_module: ${{ steps.vars.outputs.puppet_agent_module }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 805d134..bed0009 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,3 +73,4 @@ jobs: image: ${{ needs.prepare.outputs.re_image }} dockerfile: ${{ needs.prepare.outputs.re_dockerfile }} refresh: true + acceptance_test: ${{ github.event_name == 'pull_request' && 'puppetlabs/puppetlabs-stdlib' }} diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 9e31493..4c6f26f 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -8,6 +8,8 @@ run-name: > ${{ inputs.push && format('push={0}', inputs.push) || ''}} ${{ inputs.puppet_litmus && format('puppet_litmus={0}', inputs.puppet_litmus) || '' }} ${{ inputs.provision_module && format('provision_module={0}', inputs.provision_module) || '' }} + ${{ inputs.provision_task && format('provision_task={0}', inputs.provision_task) || '' }} + ${{ inputs.acceptance_test && format('acceptance={0}', inputs.acceptance_test) || '' }} on: workflow_dispatch: @@ -29,9 +31,12 @@ on: type: boolean default: true provision_task: - description: provision task (docker or docker_exp) - type: string - default: "docker" + description: provision task + type: choice + default: docker + options: + - docker + - docker_exp puppet_litmus: description: gem options (JSON Hash) type: string @@ -40,6 +45,9 @@ on: description: provision module overrides (JSON Hash) type: string default: "" + acceptance_test: + description: repo of module to acceptance test + type: string jobs: manual: @@ -53,3 +61,4 @@ jobs: provision_task: ${{ inputs.provision_task }} puppet_litmus: ${{ inputs.puppet_litmus }} provision_module: ${{ inputs.provision_module }} + acceptance_test: ${{ inputs.acceptance_test }} diff --git a/.github/workflows/template_build_deploy.yml b/.github/workflows/template_build_deploy.yml index eedea0d..6a5c862 100644 --- a/.github/workflows/template_build_deploy.yml +++ b/.github/workflows/template_build_deploy.yml @@ -25,7 +25,8 @@ on: provision_module: default: "" type: string - + acceptance_test: + type: string concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -130,7 +131,7 @@ jobs: images: needs: select name: image (${{ matrix.image_tag }}) - timeout-minutes: 5 + timeout-minutes: 10 permissions: contents: read packages: write @@ -186,68 +187,23 @@ jobs: run: | docker build --rm --no-cache -t ${IMAGE_TAG} . --label "base_image=${BASE_ID}" -f ${{ matrix.dockerfile }}.dockerfile --build-arg BASE_IMAGE_TAG=${{ matrix.base_tag }} --build-arg OS_TYPE=${{ matrix.base_image }} - - name: Smoke test setup - if: steps.build_image.outcome == 'success' || steps.build_image.conclusion == 'skipped' - id: test_ruby_setup - uses: "ruby/setup-ruby@v1" + - name: Smoke test (${{ inputs.provision_task }}) + uses: ./.github/actions/smoke-test with: - ruby-version: '3.2' - bundler-cache: true - working-directory: tests/smoke + docker_image: ${{ env.IMAGE_TAG }} + provision_task: ${{ inputs.provision_task }} + provision_module: ${{ inputs.provision_module }} - - name: Smoke test with custom provision module - if: steps.test_ruby_setup.outcome == 'success' && inputs.provision_module != '' - working-directory: tests/smoke - shell: ruby {0} - run: | - require 'yaml' - require 'json' - input = <