Skip to content

Commit

Permalink
Merge branch 'master' into issue_203
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-riddle committed May 9, 2023
2 parents 453ea57 + b0bac88 commit 9da3004
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 125 deletions.
27 changes: 12 additions & 15 deletions .github/workflows/tag_deploy_rubygem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ on:
- '[0-9]+\.[0-9]+\.[0-9]+\-[a-z]+[0-9]+'

env:
PUPPET_VERSION: '~> 6'
PUPPET_VERSION: '~> 7'
LOCAL_WORKFLOW_CONFIG_FILE: .github/workflows.local.json

jobs:
Expand Down Expand Up @@ -113,6 +113,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
prerelease: ${{ steps.tag-check.outputs.prerelease }}
tag: ${{ steps.tag-check.outputs.tag }}
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand All @@ -128,7 +129,6 @@ jobs:
annotation="$(git for-each-ref "$GITHUB_REF" --format='%(contents)' --count=1)"
annotation_title="$(echo "$annotation" | head -1)"
if [[ "$tag" =~ ^(simp-|v)?[0-9]+\.[0-9]+\.[0-9]+(-(rc|alpha|beta|pre|post)?([0-9]+)?)?$ ]]; then
if [ -n "${BASH_REMATCH[2]}" ]; then
prerelease=yes
Expand All @@ -141,30 +141,27 @@ jobs:
echo "tag=$tag" | tee -a "$GITHUB_OUTPUT"
echo "prerelease=$prerelease" | tee -a "$GITHUB_OUTPUT"
echo "annotation_title=$annotation_title" | tee -a "$GITHUB_OUTPUT"
echo "TARGET_TAG=$tag" | tee -a "$GITHUB_ENV"
# Prepare annotation body as a file for the next step
#
# * The GitHub Release render the text in this file as markdown
# * The file is needed because :set-output only supports single lines
# * The GitHub Release renders the text in this file as markdown
# * The `perl -pe` removes RPM-style date headers from the CHANGELOG,
# because they don't render well as markdown on the Release page
#
echo "RELEASE_MESSAGE<<EOF$$" >> "$GITHUB_ENV"
printf '%s\n\n' "$annotation_title" >> "$GITHUB_ENV"
echo "$annotation" | tail -n +2 | \
perl -pe 'BEGIN{undef $/;} s/\n\* (Mon|Tue|Wed|Thu|Fri|Sat|Sun) .*?\n//smg;' > /tmp/annotation.body
perl -pe 'BEGIN{undef $/;} s/\n\* (Mon|Tue|Wed|Thu|Fri|Sat|Sun) .*?\n//smg;' >> "$GITHUB_ENV"
echo "EOF$$" >> "$GITHUB_ENV"
- name: Create Release
uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ steps.tag-check.outputs.annotation_title }}
body_path: /tmp/annotation.body
prerelease: ${{ steps.tag-check.outputs.prerelease == 'yes'}}
draft: false
run: |
echo "${RELEASE_MESSAGE}" > /tmp/.commit-msg.txt
args=(--file /tmp/.commit-msg.txt)
[[ ${{ steps.tag-check.outputs.prerelease }} == yes ]] && args+=(--prerelease)
deploy-rubygem:
name: Deploy RubyGem Release
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Gemfile.lock
*.swp
*.sw[pnoqst]
.vagrant
.vendor
145 changes: 96 additions & 49 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
# The testing matrix considers ruby/puppet versions supported by SIMP:
# --------------------------------------------------------------------
# Release Puppet Ruby EOL
# SIMP 6.4 5.5 2.4.10 TBD
# SIMP 6.5 6.18 2.5.7 TBD
# ------------------------------------------------------------------------------
# This file is updated automatically as part of a puppet module baseline.
#
# The next baseline sync will overwrite any local changes to everything above
# the line "# Repo-specific content"
# ------------------------------------------------------------------------------
# The testing matrix considers ruby/puppet versions supported by SIMP and PE:
#
# https://puppet.com/docs/pe/2019.8/component_versions_in_recent_pe_releases.html
# https://puppet.com/misc/puppet-enterprise-lifecycle
# https://puppet.com/docs/pe/2018.1/overview/getting_support_for_pe.html
# ------------------------------------------------------------------------------
# Release Puppet Ruby EOL
# PE 2019.8 6.28 2.5.7 2023-07 (LTS)
# PE 2021.7 7.20 2.7.6 TBD (LTS)
---

stages:
- validation
- acceptance
- deploy

image: 'ruby:2.5'

variables:
# PUPPET_VERSION is a canary variable!
#
# The value `UNDEFINED` will (intentionally) cause `bundler install|update` to
# fail. The intended value for PUPPET_VERSION is provided by the `pup_#` YAML
# anchors. If it is still `UNDEFINED`, all the other setting from the job's
# anchor are also missing.
PUPPET_VERSION: 'UNDEFINED' # <- Matrixed jobs MUST override this (or fail)
BUNDLER_VERSION: '1.17.1'
BUNDLER_VERSION: '2.2.19'

# Force dependencies into a path the gitlab-runner user can write to.
# (This avoids some failures on Runners with misconfigured ruby environments.)
Expand All @@ -23,6 +39,55 @@ variables:
BUNDLE_BIN: .vendor/gem_install/bin
BUNDLE_NO_PRUNE: 'true'

.snippets:
before_beaker_google:
# Logic for beaker-google environments
- echo -e "\e[0Ksection_start:`date +%s`:before_script05[collapsed=true]\r\e[0KGCP environment checks"
- "if [ \"$BEAKER_HYPERVISOR\" == google ]; then mkdir -p ~/.ssh; chmod 700 ~/.ssh; test -f ~/.ssh/google_compute_engine || ssh-keygen -f ~/.ssh/google_compute_engine < /dev/null; echo 'gem \"beaker-google\"' >> Gemfile.local ; fi"
- echo -e "\e[0Ksection_end:`date +%s`:before_script05\r\e[0K"

before:
# Print important environment variables that may affect this job
- 'ruby -e "puts %(\n\n), %q(=)*80, %(\nSIMP-relevant Environment Variables:\n\n#{e=ENV.keys.grep(/^PUPPET|^SIMP|^BEAKER|MATRIX|GOOGLE/); pad=((e.map{|x| x.size}.max||0)+1); e.map{|v| %( * #{%(#{v}:).ljust(pad)} #{39.chr + ENV[v] + 39.chr}\n)}.join}\n), %q(=)*80, %(\n\n)" || :'

- echo -e "\e[0Ksection_start:`date +%s`:before_script10[collapsed=true]\r\e[0KDiagnostic ruby & gem information"
# Diagnostic ruby & gem information
- 'which ruby && ruby --version || :'
- "[[ $- == *i* ]] && echo 'Interactive shell session' || echo 'Non-interactive shell session'"
- "shopt -q login_shell && echo 'Login shell' || echo 'Not a login shell'"
- 'rvm ls || :'
- echo -e "\e[0Ksection_end:`date +%s`:before_script10\r\e[0K"

# If RVM is available, make SURE it's using the right Ruby:
# * Source rvm (to run in non-login shells)
# * Use $MATRIX_RUBY_VERSION ruby, install if not present
- echo -e "\e[0Ksection_start:`date +%s`:before_script20[collapsed=true]\r\e[0KEnsure RVM & ruby is installed"
- "if command -v rvm; then if declare -p rvm_path &> /dev/null; then source \"${rvm_path}/scripts/rvm\"; else source \"$HOME/.rvm/scripts/rvm\" || source /etc/profile.d/rvm.sh; fi; fi"
- "if command -v rvm && ! grep rvm_install_on_use_flag=1 ~/.rvmrc; then echo rvm_install_on_use_flag=1 >> ~/.rvmrc || echo '== WARNING: ~/.rvmrc is missing rvm_install_on_use_flag=1 and I failed to add it'; fi"
- "if command -v rvm; then rvm use \"$MATRIX_RUBY_VERSION\"; else echo \"rvm not detected; skipping 'rvm use'\"; fi"
- 'ruby --version || :'
- 'gem list sync || :'
- echo -e "\e[0Ksection_end:`date +%s`:before_script20\r\e[0K"

# Bundle gems (preferring cached > local > downloaded resources)
# * Try to use cached and local resources before downloading dependencies
- echo -e "\e[0Ksection_start:`date +%s`:before_script30[collapsed=true]\r\e[0KBundle gems (preferring cached > local > downloaded resources)"
- 'declare GEM_BUNDLER_VER=(-v "~> ${BUNDLER_VERSION:-2.2.6}")'
- 'declare GEM_INSTALL_CMD=(gem install --no-document)'
- 'declare BUNDLER_INSTALL_CMD=(bundle install --no-binstubs --jobs $(nproc) "${FLAGS[@]}")'
- 'mkdir -p ${GEM_HOME} ${BUNDLER_BIN}'
- 'gem list -ie "${GEM_BUNDLER_VER[@]}" --silent bundler || "${GEM_INSTALL_CMD[@]}" --local "${GEM_BUNDLER_VER[@]}" bundler || "${GEM_INSTALL_CMD[@]}" "${GEM_BUNDLER_VER[@]}" bundler'
- 'rm -rf pkg/ || :'
- 'bundle check || rm -f Gemfile.lock && ("${BUNDLER_INSTALL_CMD[@]}" --local || "${BUNDLER_INSTALL_CMD[@]}" || bundle pristine || "${BUNDLER_INSTALL_CMD[@]}") || { echo "PIPELINE: Bundler could not install everything (see log output above)" && exit 99 ; }'
- echo -e "\e[0Ksection_end:`date +%s`:before_script30\r\e[0K"

# Diagnostic bundler, ruby, and gem checks:
- echo -e "\e[0Ksection_start:`date +%s`:before_script40[collapsed=true]\r\e[0KDiagnostic bundler, ruby, and gem checks"
- 'bundle exec rvm ls || :'
- 'bundle exec which ruby || :'
- 'bundle show sync || :'
- 'bundle exec gem list sync || :'
- echo -e "\e[0Ksection_end:`date +%s`:before_script40\r\e[0K"

# bundler dependencies and caching
#
Expand All @@ -36,14 +101,7 @@ variables:
paths:
- '.vendor'
before_script:
- 'ruby -e "puts %(Environment Variables:\n * #{ENV.keys.grep(/PUPPET|SIMP|BEAKER|MATRIX/).map{|v| %(#{v} = #{ENV[v]})}.join(%(\n * ))})"'
- 'declare GEM_BUNDLER_VER=(-v "~> ${BUNDLER_VERSION:-1.16.0}")'
- 'declare GEM_INSTALL_CMD=(gem install --no-document)'
- 'declare BUNDLER_INSTALL_CMD=(bundle install --no-binstubs --jobs $(nproc) "${FLAGS[@]}")'
- 'mkdir -p ${GEM_HOME} ${BUNDLER_BIN}'
- 'gem list -ie "${GEM_BUNDLER_VER[@]}" --silent bundler || "${GEM_INSTALL_CMD[@]}" --local "${GEM_BUNDLER_VER[@]}" bundler || "${GEM_INSTALL_CMD[@]}" "${GEM_BUNDLER_VER[@]}" bundler'
- 'rm -rf pkg/ || :'
- 'bundle check || rm -f Gemfile.lock && ("${BUNDLER_INSTALL_CMD[@]}" --local || "${BUNDLER_INSTALL_CMD[@]}" || bundle pristine || "${BUNDLER_INSTALL_CMD[@]}") || { echo "PIPELINE: Bundler could not install everything (see log output above)" && exit 99 ; }'
!reference [.snippets, before]


# To avoid running a prohibitive number of tests every commit,
Expand All @@ -56,26 +114,20 @@ variables:
# Puppet Versions
#-----------------------------------------------------------------------

.pup_5_pe: &pup_5_pe
image: 'ruby:2.4'
variables:
PUPPET_VERSION: '5.5.20'
BEAKER_PUPPET_COLLECTION: 'puppet5'
MATRIX_RUBY_VERSION: '2.4'

.pup_6_18: &pup_6_18
.pup_7_x: &pup_7_x
image: 'ruby:2.5'
variables:
PUPPET_VERSION: '~> 6.18.0'
BEAKER_PUPPET_COLLECTION: 'puppet6'
MATRIX_RUBY_VERSION: '2.5'
PUPPET_VERSION: '7.21.0'
BEAKER_PUPPET_COLLECTION: 'puppet7'
MATRIX_RUBY_VERSION: '2.7'

.pup_6_18: &pup_6_x
image: 'ruby:2.5'
.pup_8_x: &pup_8_x
image: 'ruby:3.2'
variables:
PUPPET_VERSION: '~> 6.18'
BEAKER_PUPPET_COLLECTION: 'puppet6'
MATRIX_RUBY_VERSION: '2.5'
PUPPET_VERSION: '~> 8.0'
BEAKER_PUPPET_COLLECTION: 'puppet8'
MATRIX_RUBY_VERSION: '3.2'


.validation_checks: &validation_checks
stage: validation
Expand All @@ -85,7 +137,7 @@ variables:
- bundle exec rake clean
- bundle exec rake pkg:gem

.spec_tests: &spec_tests
.unit_tests: &unit_tests
stage: validation
tags: ['docker']
<<: *setup_bundler_env
Expand All @@ -101,39 +153,34 @@ variables:
<<: *setup_bundler_env


# Puppet 5.5 for PE 2018.1 support
# See: https://puppet.com/misc/puppet-enterprise-lifecycle
# --------------------------------------


pup6.18-validation:
<<: *pup_6_18
pup7-validation:
<<: *pup_7_x
<<: *validation_checks

pup6.18-unit:
<<: *pup_6_18
<<: *spec_tests
pup7.x-unit:
<<: *pup_7_x
<<: *unit_tests

pup6.latest-validation:
<<: *pup_6_x
pup8.x-validation:
<<: *pup_8_x
<<: *validation_checks

pup6.latest-unit:
<<: *pup_6_x
<<: *spec_tests
pup8.x-unit:
<<: *pup_8_x
<<: *unit_tests

# Acceptance tests
# ==============================================================================
acceptance:
<<: *acceptance_base
<<: *pup_6_18
<<: *pup_7_x
script:
- 'bundle exec rake acceptance'
allow_failure: true # FIXME: add docker to GLCI beaker runners

fips-acceptance:
<<: *acceptance_base
<<: *pup_6_18
<<: *pup_7_x
script:
- 'BEAKER_fips=yes bundle exec rake acceptance'
allow_failure: true
107 changes: 107 additions & 0 deletions rakelib/gitlab_ci.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
require 'net/http'
require 'uri'
require 'json'
require 'yaml'


def gitlab_ci_lint( gitlab_ci_url, gitlab_ci_yml_path )
unless File.exists? gitlab_ci_yml_path
warn "WARNING: no GitLab CI config found at '#{gitlab_ci_yml_path}'"
warn '(skipping)'
return
end

puts "Querying #{gitlab_ci_url} ...\n\n" if $VERBOSE
uri = URI.parse( gitlab_ci_url )
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request['PRIVATE-TOKEN'] = ENV['GITLAB_API_TOKEN'] || fail('Missing env var: GITLAB_API_TOKEN')

content = YAML.load_file(gitlab_ci_yml_path)
request.body = JSON.dump({ "content" => content.to_json })
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end

if response.code_type != Net::HTTPOK
msg = "ERROR: Could not use CI linter at #{gitlab_ci_url} " +
"(#{response.code}: #{response.message})\n\n"

elsif JSON.parse(response.body)['valid']
puts "#{File.basename(gitlab_ci_yml_path)} is valid\n\n"
else
msg = "ERROR: #{File.basename(gitlab_ci_yml_path)} is not valid!\n\n"
data = JSON.parse response.body
data['errors'].each do |error|
msg += " * #{error}\n"
end
msg += "\n\n"
msg += "Path: '#{gitlab_ci_yml_path}'\n"

msg
end
abort msg if msg
end


namespace :gitlab_ci do
desc <<~MSG
Check the .gitlab-ci.yml for errors
Arguments:
* gitlab_url ex: https://gitlab.com
env var default: `GITLAB_URL`
* project_id ex: group-name/project-name
env var default: `GITLAB_PROJECT`
* gitlab_ci_yml_path default: .gitlab-ci.yml
env var: `GITLAB_CI_YML_PATH`
If `gitlab_url` and `project_id` are not provided by argument or env var,
the task will look for a .gitlab-project-api.yaml file with those keys
MSG
task :lint, [:gitlab_url, :project_id] do |t, args|
args.with_defaults(
gitlab_url: ENV['GITLAB_URL'],
project_id: ENV['GITLAB_PROJECT'],
gitlab_ci_yml_path: (ENV['GITLAB_CI_YML_PATH'] || '.gitlab-ci.yml')
)
gitlab_url = args.gitlab_url
project_id = args.project_id
gitlab_ci_yml_path = args.gitlab_ci_yml_path

unless(gitlab_url && project_id)
warn 'WARNING: no gitlab_url or project_id given via task arg or env var' if $VERBOSE
warn 'Checking for .gitlab-project-api.yaml...' if $VERBOSE
unless File.exists? '.gitlab-project-api.yaml'
fail( [
"\nERROR: no gitlab_url or project_id given via task arg or env va
r",
"and no .gitlab-project-api.yaml file found\n",
"FATAL: Task must be given values for #{args.names}",
" See `rake D #{t.name}` for details\n\n",
].join("\n"))
else
require 'yaml'
warb 'Reading .gitlab-project-api.yaml...' if $VERBOSE
data = YAML.load_file('.gitlab-project-api.yaml')
gitlab_url, project_id = data['gitlab_url'], data['project_id']
project_id.gsub!('/','%2F')
warn "Using data:", data.to_yaml if $VERBOSE
end
end

gitlab_ci_yml_paths = gitlab_ci_yml_path.split(':')
gitlab_ci_url = "#{gitlab_url}/api/v4/projects/#{project_id}/ci/lint"
puts "CI Linting using GitLab URI: #{gitlab_ci_url}:" if $VERBOSE
puts gitlab_ci_yml_paths.map{|x| "\t- #{x}\n"}.join, '' if $VERBOSE

gitlab_ci_yml_paths.each do |g|
gitlab_ci_lint(gitlab_ci_url, g)
end

end
end
Loading

0 comments on commit 9da3004

Please sign in to comment.