simp-beaker-helpers 1.21.4 → 1.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.fips_fixtures +1 -0
- data/.github/workflows/pr_glci.yml +190 -0
- data/.github/workflows/pr_glci_cleanup.yml +105 -0
- data/.github/workflows/pr_glci_manual.yml +143 -0
- data/.github/workflows/tag_deploy_rubygem.yml +152 -0
- data/.gitlab-ci.yml +24 -37
- data/CHANGELOG.md +20 -0
- data/README.md +63 -5
- data/lib/simp/beaker_helpers.rb +146 -46
- data/lib/simp/beaker_helpers/version.rb +1 -1
- data/lib/simp/rake/beaker.rb +6 -0
- data/spec/acceptance/suites/default/install_simp_deps_repo_spec.rb +17 -5
- data/spec/acceptance/suites/fips_from_fixtures/00_default_spec.rb +1 -0
- metadata +6 -3
- data/.travis.yml +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf4dabba2a12366f3acb4e850cd1894df06f7ab2f1de040f384351c8a2fdc3a1
|
4
|
+
data.tar.gz: ee3ee574fbb0165bc5354cc5a5bc5a9355add5da3412f5e65d2e3d27274d1f4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c11025a91bc2e4cb079531e9930c54e7540b759bc365bb7a676c90a1c6ce50b5af4f610fb22e3c74b54f8c1d858d71ff4f12b30ba136ef5d1788255727c0df91
|
7
|
+
data.tar.gz: 50696f976eba788b3ed287af8aab9925ff237ba8d1b524ea0eaf04dbd97b11192a350cde65004696f6b0d83c3ce0bae1561fd408dce6d334aab57745cc1e7f40
|
data/.fips_fixtures
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
---
|
2
2
|
fixtures:
|
3
3
|
repositories:
|
4
|
+
crypto_policy: https://github.com/simp/pupmod-simp-crypto_policy
|
4
5
|
fips: https://github.com/simp/pupmod-simp-fips
|
5
6
|
augeasproviders_core: https://github.com/simp/augeasproviders_core
|
6
7
|
augeasproviders_grub: https://github.com/simp/augeasproviders_grub
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# Push/Trigger a GitLab CI pipeline for the PR HEAD, **ONLY IF:**
|
2
|
+
#
|
3
|
+
# 1. The .gitlab-ci.yaml file exists and validates
|
4
|
+
# 2. The PR submitter has write access to the target repository.
|
5
|
+
#
|
6
|
+
# ------------------------------------------------------------------------------
|
7
|
+
#
|
8
|
+
# NOTICE: **This file is maintained with puppetsync**
|
9
|
+
#
|
10
|
+
# This file is updated automatically as part of a puppet module baseline.
|
11
|
+
#
|
12
|
+
# The next baseline sync will overwrite any local changes to this file!
|
13
|
+
#
|
14
|
+
# ==============================================================================
|
15
|
+
#
|
16
|
+
# GitHub Action Secrets variables available for this pipeline:
|
17
|
+
#
|
18
|
+
# GitHub Secret variable Type Notes
|
19
|
+
# ------------------------ -------- ----------------------------------------
|
20
|
+
# GITLAB_API_PRIVATE_TOKEN Secure Should have `api` scope
|
21
|
+
# GITLAB_API_URL Optional
|
22
|
+
#
|
23
|
+
# The secure vars will be filtered in GitHub Actions log output, and aren't
|
24
|
+
# provided to untrusted builds (i.e, triggered by PR from another repository)
|
25
|
+
#
|
26
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
27
|
+
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
28
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!V!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
29
|
+
#
|
30
|
+
# DO NOT MODIFY this workflow, unless you **REALLY** know what you are doing.
|
31
|
+
#
|
32
|
+
# This workflow bypasses some of the built-in protections of the
|
33
|
+
# `pull_request_target` event by explicitly checking out the PR's **HEAD**.
|
34
|
+
# Without being VERY CAREFUL, this could easily allow a malcious PR
|
35
|
+
# contributor the chance to access secrets or a GITHUB_TOKEN with write scope!!
|
36
|
+
#
|
37
|
+
# The jobs in this workflow are designed to handle this safely -- but DO NOT
|
38
|
+
# assume any alterations will also be safe.
|
39
|
+
#
|
40
|
+
# For general information, see:
|
41
|
+
#
|
42
|
+
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target
|
43
|
+
#
|
44
|
+
# For further information, or if ANY of this seems confusing or unecessary:
|
45
|
+
#
|
46
|
+
# ASK FOR ASSISTANCE **BEFORE** ATTEMPTING TO MODIFY THIS WORKFLOW.
|
47
|
+
#
|
48
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
49
|
+
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
50
|
+
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!V!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
51
|
+
#
|
52
|
+
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows
|
53
|
+
#
|
54
|
+
---
|
55
|
+
name: PR GLCI
|
56
|
+
on:
|
57
|
+
pull_request_target:
|
58
|
+
types: [opened, reopened, synchronize]
|
59
|
+
|
60
|
+
jobs:
|
61
|
+
|
62
|
+
# The ONLY reason we can validate the PR HEAD's content safely here is that
|
63
|
+
# we restrict ourselves to sending data elsewhere.
|
64
|
+
glci-syntax:
|
65
|
+
name: '.gitlab-ci.yml Syntax'
|
66
|
+
runs-on: ubuntu-16.04
|
67
|
+
outputs:
|
68
|
+
valid: ${{ steps.validate-glci-file.outputs.valid }}
|
69
|
+
steps:
|
70
|
+
- uses: actions/checkout@v2
|
71
|
+
with:
|
72
|
+
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
73
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
74
|
+
- name: 'Validate GLCI file syntax'
|
75
|
+
id: validate-glci-file
|
76
|
+
uses: simp/github-action-gitlab-ci-syntax-check@main
|
77
|
+
with:
|
78
|
+
gitlab_api_private_token: ${{ secrets.GITLAB_API_PRIVATE_TOKEN }}
|
79
|
+
gitlab_api_url: ${{ secrets.GITLAB_API_URL }} # https://gitlab.com/api/v4
|
80
|
+
|
81
|
+
contributor-permissions:
|
82
|
+
name: 'PR contributor check'
|
83
|
+
runs-on: ubuntu-18.04
|
84
|
+
outputs:
|
85
|
+
permitted: ${{ steps.user-repo-permissions.outputs.permitted }}
|
86
|
+
steps:
|
87
|
+
- uses: actions/github-script@v3
|
88
|
+
id: user-repo-permissions
|
89
|
+
with:
|
90
|
+
github-token: ${{secrets.GITHUB_TOKEN}}
|
91
|
+
# See:
|
92
|
+
# - https://octokit.github.io/rest.js/
|
93
|
+
# - https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#get-repository-permissions-for-a-user
|
94
|
+
script: |
|
95
|
+
const project_permission = await github.request('GET /repos/{owner}/{repo}/collaborators/{username}/permission', {
|
96
|
+
headers: {
|
97
|
+
accept: 'application/vnd.github.v3+json'
|
98
|
+
},
|
99
|
+
owner: context.repo.owner,
|
100
|
+
repo: context.repo.repo,
|
101
|
+
username: context.payload.sender.login,
|
102
|
+
})
|
103
|
+
const has_write_access = perm_lvl => (perm_lvl == "admin" || perm_lvl == "write" )
|
104
|
+
const write_access_desc = perm_bool => (perm_bool ? "PERMISSION OK" : "PERMISSION DENIED" )
|
105
|
+
if( has_write_access(project_permission.data.permission )){
|
106
|
+
core.setOutput( 'permitted', 'true' )
|
107
|
+
} else {
|
108
|
+
core.setOutput( 'permitted', 'false' )
|
109
|
+
console.log(`::error ::payload user '${context.payload.sender.login}' does not have CI trigger permission for '${context.repository}; not triggering external CI'`)
|
110
|
+
}
|
111
|
+
console.log(`== payload user '${context.payload.sender.login}' CI trigger permission for '${context.repo.owner}': ${write_access_desc(has_write_access(project_permission.data.permission))}`)
|
112
|
+
|
113
|
+
|
114
|
+
trigger-when-user-has-repo-permissions:
|
115
|
+
name: 'Trigger CI [trusted users only]'
|
116
|
+
needs: [ glci-syntax, contributor-permissions ]
|
117
|
+
# This conditional provides an extra safety control, in case the workflow's
|
118
|
+
# `on` section is inadventently modified without considering the security
|
119
|
+
# implications.
|
120
|
+
#
|
121
|
+
# This job will ONLY trigger on:
|
122
|
+
#
|
123
|
+
# - [x] pull_request_target event: github.event_name == 'pull_request_target'
|
124
|
+
# AND:
|
125
|
+
# - [x] Newly-opened PRs: github.event.action == 'opened'
|
126
|
+
# - [x] Re-opened PRs: github.event.action == 'reopened'
|
127
|
+
# - [x] Commits are added to PR: github.event.action == 'synchronize'
|
128
|
+
# AND:
|
129
|
+
# - [x] .gitlab-ci.yml exists/ok: needs.glci-syntax.outputs.valid == 'true'
|
130
|
+
#
|
131
|
+
# [Not implemented] It should NEVER trigger on:
|
132
|
+
#
|
133
|
+
# - [ ] Merged PRs: github.event.pull_request.merged == 'false'
|
134
|
+
# - (the downstream GitLab mirror will take care of that)
|
135
|
+
# - Not implemented: For some reason, this conditional always fails
|
136
|
+
# - Unnecessary if on>pull_request_target>types doesn't include 'closed'
|
137
|
+
if: github.event_name == 'pull_request_target' && ( github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' ) && github.event.pull_request.merged != 'true' && needs.glci-syntax.outputs.valid == 'true' && needs.contributor-permissions.outputs.permitted == 'true'
|
138
|
+
runs-on: ubuntu-18.04
|
139
|
+
steps:
|
140
|
+
# Things we'd like to do:
|
141
|
+
# - [ ] if there's no GitLab mirror, make one
|
142
|
+
# - [ ] if there's no GitLab <-> GitHub integration, make one
|
143
|
+
# - [ ] if there's no PR check on the main GitHub branch, make one (?)
|
144
|
+
# - [x] Cancel any GLCI pipelines already pending/running for this branch
|
145
|
+
# - "created|waiting_for_resource|preparing|pending|running"
|
146
|
+
# - Exception: don't cancel existing pipeline for our own commit
|
147
|
+
# - [x] if PR: force-push branch to GitLab
|
148
|
+
- uses: actions/checkout@v2
|
149
|
+
if: needs.contributor-permissions.outputs.permitted == 'true'
|
150
|
+
with:
|
151
|
+
clean: true
|
152
|
+
fetch-depth: 0 # Need full checkout to push to gitlab mirror
|
153
|
+
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
154
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
155
|
+
|
156
|
+
- name: Trigger CI when user has Repo Permissions
|
157
|
+
if: needs.contributor-permissions.outputs.permitted == 'true'
|
158
|
+
uses: simp/github-action-gitlab-ci-pipeline-trigger@v1
|
159
|
+
with:
|
160
|
+
git_branch: ${{ github.event.pull_request.head.ref }} # TODO check for/avoid protected branches?
|
161
|
+
git_hashref: ${{ github.event.pull_request.head.sha }}
|
162
|
+
gitlab_api_private_token: ${{ secrets.GITLAB_API_PRIVATE_TOKEN }}
|
163
|
+
gitlab_group: ${{ github.event.organization.login }}
|
164
|
+
github_repository: ${{ github.repository }}
|
165
|
+
github_repository_owner: ${{ github.repository_owner }}
|
166
|
+
|
167
|
+
- name: When user does NOT have Repo Permissions
|
168
|
+
if: needs.contributor-permissions.outputs.permitted == 'false'
|
169
|
+
continue-on-error: true
|
170
|
+
run: |
|
171
|
+
echo "Ending gracefully; Contributor $GITHUB_ACTOR does not have permission to trigger CI"
|
172
|
+
false
|
173
|
+
|
174
|
+
### examine_contexts:
|
175
|
+
### name: 'Examine Context contents'
|
176
|
+
### if: always()
|
177
|
+
### runs-on: ubuntu-16.04
|
178
|
+
### needs: [ glci-syntax, contributor-permissions ]
|
179
|
+
### steps:
|
180
|
+
### - name: Dump contexts
|
181
|
+
### env:
|
182
|
+
### GITHUB_CONTEXT: ${{ toJson(github) }}
|
183
|
+
### run: echo "$GITHUB_CONTEXT"
|
184
|
+
### - name: Dump needs context
|
185
|
+
### env:
|
186
|
+
### ENV_CONTEXT: ${{ toJson(needs) }}
|
187
|
+
### run: echo "$ENV_CONTEXT"
|
188
|
+
### - name: Dump env vars
|
189
|
+
### run: env | sort
|
190
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# When a PR is closed, clean up any associated GitLab CI pipelines & branch
|
2
|
+
#
|
3
|
+
# * Cancels all GLCI pipelines associated with the PR HEAD ref (branch)
|
4
|
+
# * Removes the PR HEAD branch from the corresponding gitlab.com/org/ project
|
5
|
+
#
|
6
|
+
# ------------------------------------------------------------------------------
|
7
|
+
#
|
8
|
+
# NOTICE: **This file is maintained with puppetsync**
|
9
|
+
#
|
10
|
+
# This file is updated automatically as part of a standardized asset baseline.
|
11
|
+
#
|
12
|
+
# The next baseline sync will overwrite any local changes to this file!
|
13
|
+
#
|
14
|
+
# ==============================================================================
|
15
|
+
#
|
16
|
+
# GitHub Action Secrets variables available for this pipeline:
|
17
|
+
#
|
18
|
+
# GitHub Secret variable Type Notes
|
19
|
+
# ------------------------ -------- ----------------------------------------
|
20
|
+
# GITLAB_API_PRIVATE_TOKEN Secure Should have `api` scope
|
21
|
+
# GITLAB_API_URL Optional
|
22
|
+
#
|
23
|
+
# The secure vars will be filtered in GitHub Actions log output, and aren't
|
24
|
+
# provided to untrusted builds (i.e, triggered by PR from another repository)
|
25
|
+
#
|
26
|
+
# ------------------------------------------------------------------------------
|
27
|
+
#
|
28
|
+
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows
|
29
|
+
#
|
30
|
+
---
|
31
|
+
name: PR GLCI Cleanup
|
32
|
+
on:
|
33
|
+
pull_request_target:
|
34
|
+
types: [closed]
|
35
|
+
|
36
|
+
jobs:
|
37
|
+
cleanup-glci-branch:
|
38
|
+
name: 'Clean up GLCI'
|
39
|
+
# This conditional provides an extra safety control, in case the workflow's
|
40
|
+
# `on` section is inadventently modified without considering the security
|
41
|
+
# implications.
|
42
|
+
if: github.event_name == 'pull_request_target' && github.event.action == 'closed'
|
43
|
+
runs-on: ubuntu-18.04
|
44
|
+
steps:
|
45
|
+
- uses: actions/checkout@v2
|
46
|
+
with:
|
47
|
+
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
48
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
49
|
+
- name: Trigger CI when user has Repo Permissions
|
50
|
+
env:
|
51
|
+
GITLAB_SERVER_URL: ${{ secrets.GITLAB_SERVER_URL }} # https://gitlab.com
|
52
|
+
GITLAB_API_URL: ${{ secrets.GITLAB_API_URL }} # https://gitlab.com/api/v4
|
53
|
+
GITLAB_ORG: ${{ github.event.organization.login }}
|
54
|
+
GITLAB_API_PRIVATE_TOKEN: ${{ secrets.GITLAB_API_PRIVATE_TOKEN }}
|
55
|
+
GIT_BRANCH: ${{ github.event.pull_request.head.ref }}
|
56
|
+
run: |
|
57
|
+
GITLAB_SERVER_URL="${GITLAB_SERVER_URL:-https://gitlab.com}"
|
58
|
+
GITLAB_API_URL="${GITLAB_API_URL:-${GITLAB_SERVER_URL}/api/v4}"
|
59
|
+
GIT_BRANCH="${GIT_BRANCH:-GITHUB_HEAD_REF}"
|
60
|
+
GITXXB_REPO_NAME="${GITHUB_REPOSITORY/$GITHUB_REPOSITORY_OWNER\//}"
|
61
|
+
GITLAB_PROJECT_ID="${GITLAB_ORG}%2F${GITXXB_REPO_NAME}"
|
62
|
+
# --http1.0 avoids an HTTP/2 load balancing issue when run from GA
|
63
|
+
CURL_CMD=(curl --http1.0 --fail --silent --show-error \
|
64
|
+
--header "Authorization: Bearer $GITLAB_API_PRIVATE_TOKEN" \
|
65
|
+
--header "Content-Type: application/json" \
|
66
|
+
--header "Accept: application/json" \
|
67
|
+
)
|
68
|
+
|
69
|
+
# Cancel any active/pending GitLab CI pipelines for the same project+branch
|
70
|
+
active_pipeline_ids=()
|
71
|
+
for pipe_status in created waiting_for_resource preparing pending running; do
|
72
|
+
echo " ---- checking for CI pipelines with status '$pipe_status' for project '$GITLAB_PROJECT_ID', branch '$GIT_BRANCH'"
|
73
|
+
url="${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/pipelines?ref=${GIT_BRANCH}&status=${pipe_status}"
|
74
|
+
active_pipelines="$("${CURL_CMD[@]}" "$url" | jq -r '.[] | .id , .web_url')"
|
75
|
+
active_pipeline_ids+=($(echo "$active_pipelines" | grep -E '^[0-9]*$'))
|
76
|
+
printf "$active_pipelines\n\n"
|
77
|
+
done
|
78
|
+
if [ "${#active_pipeline_ids[@]}" -gt 0 ]; then
|
79
|
+
printf "\nFound %s active pipeline ids:\n" "${#active_pipeline_ids[@]}"
|
80
|
+
echo "${active_pipeline_ids[@]}"
|
81
|
+
for pipe_id in "${active_pipeline_ids[@]}"; do
|
82
|
+
printf "\n ------ Cancelling pipeline ID %s...\n" "$pipe_id"
|
83
|
+
"${CURL_CMD[@]}" --request POST "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/pipelines/${pipe_id}/cancel"
|
84
|
+
done
|
85
|
+
else
|
86
|
+
echo No active pipelines found
|
87
|
+
fi
|
88
|
+
|
89
|
+
echo "== Removing $GIT_BRANCH from gitlab"
|
90
|
+
git remote add gitlab "https://oauth2:${GITLAB_API_PRIVATE_TOKEN}@${GITLAB_SERVER_URL#*://}/${GITLAB_ORG}/${GITXXB_REPO_NAME}.git"
|
91
|
+
git push gitlab ":${GIT_BRANCH}" -f || : # attempt to un-weird GLCI's `changed` tracking
|
92
|
+
|
93
|
+
### examine_contexts:
|
94
|
+
### name: 'Examine Context contents'
|
95
|
+
### if: always()
|
96
|
+
### runs-on: ubuntu-16.04
|
97
|
+
### steps:
|
98
|
+
### - name: Dump contexts
|
99
|
+
### env:
|
100
|
+
### GITHUB_CONTEXT: ${{ toJson(github) }}
|
101
|
+
### run: echo "$GITHUB_CONTEXT"
|
102
|
+
### run: echo "$ENV_CONTEXT"
|
103
|
+
### - name: Dump env vars
|
104
|
+
### run: env | sort
|
105
|
+
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Manually trigger GLCI pipelines for a PR
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
#
|
4
|
+
# NOTICE: **This file is maintained with puppetsync**
|
5
|
+
#
|
6
|
+
# This file is updated automatically as part of a standardized asset baseline.
|
7
|
+
#
|
8
|
+
# The next baseline sync will overwrite any local changes to this file!
|
9
|
+
#
|
10
|
+
# ==============================================================================
|
11
|
+
#
|
12
|
+
# This pipeline uses the following GitHub Action Secrets:
|
13
|
+
#
|
14
|
+
# GitHub Secret variable Type Notes
|
15
|
+
# ------------------------ -------- ----------------------------------------
|
16
|
+
# GITLAB_API_PRIVATE_TOKEN Required GitLab token (should have `api` scope)
|
17
|
+
# NO_SCOPE_GITHUB_TOKEN Required GitHub token (should have no scopes)
|
18
|
+
# GITLAB_SERVER_URL Optional Specify a GL server other than gitlab.com
|
19
|
+
# The secure vars will be filtered in GitHub Actions log output, and aren't
|
20
|
+
# provided to untrusted builds (i.e, triggered by PR from another repository)
|
21
|
+
#
|
22
|
+
# ------------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
# NOTES:
|
25
|
+
# It is necessary to provide NO_SCOPE_GITHUB_TOKEN because $secrets.GITHUB_AUTO
|
26
|
+
# is NOT provide to manually-triggered (`workflow_dispatch`) events, in order
|
27
|
+
# to prevent recursive triggers between workflows
|
28
|
+
#
|
29
|
+
# Reference:
|
30
|
+
#
|
31
|
+
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token
|
32
|
+
---
|
33
|
+
name: 'Manual: PR GLCI'
|
34
|
+
|
35
|
+
on:
|
36
|
+
workflow_dispatch:
|
37
|
+
inputs:
|
38
|
+
pr_number:
|
39
|
+
description: "PR number to trigger GLCI"
|
40
|
+
required: true
|
41
|
+
|
42
|
+
jobs:
|
43
|
+
glci-syntax:
|
44
|
+
name: '.gitlab-ci.yml Syntax'
|
45
|
+
runs-on: ubuntu-18.04
|
46
|
+
outputs:
|
47
|
+
valid: ${{ steps.validate-glci-file.outputs.valid }}
|
48
|
+
pr_head_ref: ${{ steps.get-pr.outputs.pr_head_ref }}
|
49
|
+
pr_head_sha: ${{ steps.get-pr.outputs.pr_head_sha }}
|
50
|
+
pr_head_label: ${{ steps.get-pr.outputs.pr_head_label }}
|
51
|
+
pr_head_full_name: ${{ steps.get-pr.outputs.pr_full_name }}
|
52
|
+
steps:
|
53
|
+
- uses: actions/github-script@v3
|
54
|
+
id: get-pr
|
55
|
+
with:
|
56
|
+
github-token: ${{secrets.NO_SCOPE_GITHUB_TOKEN}}
|
57
|
+
# See:
|
58
|
+
# - https://octokit.github.io/rest.js/
|
59
|
+
script: |
|
60
|
+
console.log(`== pr number: ${context.payload.inputs.pr_number}`)
|
61
|
+
const pr = await github.request('get /repos/{owner}/{repo}/pulls/{pull_number}', {
|
62
|
+
headers: {
|
63
|
+
accept: 'application/vnd.github.v3+json'
|
64
|
+
},
|
65
|
+
owner: context.repo.owner,
|
66
|
+
repo: context.repo.repo,
|
67
|
+
pull_number: context.payload.inputs.pr_number
|
68
|
+
});
|
69
|
+
|
70
|
+
console.log("\n\n== pr\n");
|
71
|
+
console.log(pr);
|
72
|
+
console.log("\n\n== pr.data.head\n");
|
73
|
+
console.log(pr.data.head);
|
74
|
+
console.log(pr.status);
|
75
|
+
|
76
|
+
// PR must have been returned
|
77
|
+
if ( pr.status != 200 ) {
|
78
|
+
//#console.log(`::error ::Error looking up PR \#${context.payload.inputs.pr_number}: HTTP Response ${pr.status}`)
|
79
|
+
return(false)
|
80
|
+
}
|
81
|
+
|
82
|
+
// TODO: should either of these conditions really prevent a GLCI trigger?
|
83
|
+
if ( pr.data.state != 'open' ) {
|
84
|
+
console.log(`::error ::PR# ${context.payload.inputs.pr_number} is not open`)
|
85
|
+
}
|
86
|
+
if ( pr.data.merged ) {
|
87
|
+
console.log(`::error ::PR# ${context.payload.inputs.pr_number} is already merged`)
|
88
|
+
}
|
89
|
+
core.setOutput( 'pr_head_sha', pr.data.head.sha )
|
90
|
+
core.setOutput( 'pr_head_ref', pr.data.head.ref )
|
91
|
+
core.setOutput( 'pr_head_label', pr.data.head.label )
|
92
|
+
core.setOutput( 'pr_head_full_name', pr.data.head.full_name )
|
93
|
+
- uses: actions/checkout@v2
|
94
|
+
with:
|
95
|
+
repository: ${{ steps.get-pr.outputs.pr_head_full_name }}
|
96
|
+
ref: ${{ steps.get-pr.outputs.pr_head_sha }}
|
97
|
+
token: ${{secrets.NO_SCOPE_GITHUB_TOKEN}}
|
98
|
+
clean: true
|
99
|
+
- name: 'Validate GLCI file syntax'
|
100
|
+
id: validate-glci-file
|
101
|
+
uses: simp/github-action-gitlab-ci-syntax-check@main
|
102
|
+
with:
|
103
|
+
gitlab_api_private_token: ${{ secrets.GITLAB_API_PRIVATE_TOKEN }}
|
104
|
+
gitlab_api_url: ${{ secrets.GITLAB_API_URL }} # https://gitlab.com/api/v4
|
105
|
+
|
106
|
+
trigger-when-user-has-repo-permissions:
|
107
|
+
name: 'Trigger CI'
|
108
|
+
needs: [ glci-syntax ]
|
109
|
+
runs-on: ubuntu-18.04
|
110
|
+
steps:
|
111
|
+
- uses: actions/checkout@v2
|
112
|
+
with:
|
113
|
+
repository: ${{ needs.glci-syntax.outputs.pr_head_full_name }}
|
114
|
+
ref: ${{ needs.glci-syntax.outputs.pr_head_sha }}
|
115
|
+
token: ${{secrets.NO_SCOPE_GITHUB_TOKEN}}
|
116
|
+
fetch-depth: 0 # Need full checkout to push to gitlab mirror
|
117
|
+
clean: true
|
118
|
+
- name: Trigger CI when user has Repo Permissions
|
119
|
+
uses: simp/github-action-gitlab-ci-pipeline-trigger@v1
|
120
|
+
with:
|
121
|
+
git_hashref: ${{ needs.glci-syntax.outputs.pr_head_sha }}
|
122
|
+
git_branch: ${{ needs.glci-syntax.outputs.pr_head_ref }}
|
123
|
+
gitlab_api_private_token: ${{ secrets.GITLAB_API_PRIVATE_TOKEN }}
|
124
|
+
gitlab_group: ${{ github.event.organization.login }}
|
125
|
+
github_repository: ${{ github.repository }}
|
126
|
+
github_repository_owner: ${{ github.repository_owner }}
|
127
|
+
|
128
|
+
### examine_contexts:
|
129
|
+
### needs: [ glci-syntax ]
|
130
|
+
### name: 'Examine Context contents'
|
131
|
+
### if: always()
|
132
|
+
### runs-on: ubuntu-18.04
|
133
|
+
### steps:
|
134
|
+
### - name: Dump contexts
|
135
|
+
### env:
|
136
|
+
### GITHUB_CONTEXT: ${{ toJson(github) }}
|
137
|
+
### run: echo "$GITHUB_CONTEXT"
|
138
|
+
### - name: Dump 'needs' context
|
139
|
+
### env:
|
140
|
+
### ENV_CONTEXT: ${{ toJson(needs) }}
|
141
|
+
### run: echo "$ENV_CONTEXT"
|
142
|
+
### - name: Dump env vars
|
143
|
+
### run: env | sort
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# Build & Deploy RubyGem & GitHub release when a SemVer tag is pushed
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
#
|
4
|
+
# NOTICE: **This file is maintained with puppetsync**
|
5
|
+
#
|
6
|
+
# This file is updated automatically as part of a standardized asset baseline.
|
7
|
+
#
|
8
|
+
# The next baseline sync will overwrite any local changes to this file!
|
9
|
+
#
|
10
|
+
# ==============================================================================
|
11
|
+
#
|
12
|
+
# This pipeline uses the following GitHub Action Secrets:
|
13
|
+
#
|
14
|
+
# GitHub Secret variable Type Notes
|
15
|
+
# ------------------------ -------- ----------------------------------------
|
16
|
+
# RUBYGEMS_API_KEY Required
|
17
|
+
#
|
18
|
+
# ------------------------------------------------------------------------------
|
19
|
+
#
|
20
|
+
# NOTES:
|
21
|
+
#
|
22
|
+
# * The CHANGLOG text is altered to remove RPM-style date headers, which don't
|
23
|
+
# render well as markdown on the GitHub release pages
|
24
|
+
---
|
25
|
+
name: 'Tag: Release to GitHub & rubygems.org'
|
26
|
+
|
27
|
+
on:
|
28
|
+
push:
|
29
|
+
tags:
|
30
|
+
- '[0-9]+\.[0-9]+\.[0-9]+'
|
31
|
+
|
32
|
+
env:
|
33
|
+
PUPPET_VERSION: '~> 6'
|
34
|
+
LOCAL_WORKFLOW_CONFIG_FILE: .github/workflows.local.json
|
35
|
+
|
36
|
+
jobs:
|
37
|
+
releng-checks:
|
38
|
+
name: "RELENG checks"
|
39
|
+
runs-on: ubuntu-18.04
|
40
|
+
outputs:
|
41
|
+
build_command: ${{ steps.commands.outputs.build_command }}
|
42
|
+
release_command: ${{ steps.commands.outputs.release_command }}
|
43
|
+
steps:
|
44
|
+
- name: "Assert '${{ github.ref }}' is a tag"
|
45
|
+
run: '[[ "$GITHUB_REF" =~ ^refs/tags/ ]] || { echo "::error ::GITHUB_REF is not a tag: ${GITHUB_REF}"; exit 1 ; }'
|
46
|
+
- uses: actions/checkout@v2
|
47
|
+
with:
|
48
|
+
ref: ${{ github.ref }}
|
49
|
+
clean: true
|
50
|
+
- name: Determing build and release commands
|
51
|
+
id: commands
|
52
|
+
run: |
|
53
|
+
# By default, these are the standard tasks from "bundler/gem_tasks"
|
54
|
+
# To override them in the LOCAL_WORKFLOW_CONFIG_FILE
|
55
|
+
GEM_BUILD_COMMAND='bundle exec rake build'
|
56
|
+
GEM_RELEASE_COMMAND='gem push pkg/*.gem'
|
57
|
+
if jq -r '. | keys' "$LOCAL_WORKFLOW_CONFIG_FILE" 2>/dev/null | \
|
58
|
+
grep -w '"gem_build_command"' &> /dev/null; then
|
59
|
+
GEM_BUILD_COMMAND="$(jq .gem_build_command "$LOCAL_WORKFLOW_CONFIG_FILE" )"
|
60
|
+
fi
|
61
|
+
if jq -r '. | keys' "$LOCAL_WORKFLOW_CONFIG_FILE" 2>/dev/null | \
|
62
|
+
grep -w '"gem_release_command"' &> /dev/null; then
|
63
|
+
GEM_RELEASE_COMMAND="$(jq .gem_release_command "$LOCAL_WORKFLOW_CONFIG_FILE" )"
|
64
|
+
fi
|
65
|
+
echo "::set-output name=build_command::${GEM_BUILD_COMMAND}"
|
66
|
+
echo "::set-output name=release_command::${GEM_RELEASE_COMMAND}"
|
67
|
+
- uses: ruby/setup-ruby@v1
|
68
|
+
with:
|
69
|
+
ruby-version: 2.5
|
70
|
+
bundler-cache: true
|
71
|
+
- name: Test build the package
|
72
|
+
run: "${{ steps.commands.outputs.build_command }}"
|
73
|
+
|
74
|
+
create-github-release:
|
75
|
+
name: Deploy GitHub Release
|
76
|
+
needs: [ releng-checks ]
|
77
|
+
runs-on: ubuntu-18.04
|
78
|
+
steps:
|
79
|
+
- name: Checkout code
|
80
|
+
uses: actions/checkout@v2
|
81
|
+
with:
|
82
|
+
ref: ${{ github.ref }}
|
83
|
+
clean: true
|
84
|
+
fetch-depth: 0
|
85
|
+
- name: Get tag & annotation info (${{github.ref}})
|
86
|
+
id: tag-check
|
87
|
+
run: |
|
88
|
+
tag="${GITHUB_REF/refs\/tags\//}"
|
89
|
+
annotation="$(git for-each-ref "$GITHUB_REF" --format='%(contents)' --count=1)"
|
90
|
+
annotation_title="$(echo "$annotation" | head -1)"
|
91
|
+
|
92
|
+
echo "::set-output name=tag::${tag}"
|
93
|
+
echo "::set-output name=annotation_title::${annotation_title}"
|
94
|
+
|
95
|
+
# Prepare annotation body as a file for the next step
|
96
|
+
#
|
97
|
+
# * The GitHub Release render the text in this file as markdown
|
98
|
+
# * The file is needed because :set-output only supports single lines
|
99
|
+
# * The `perl -pe` removes RPM-style date headers from the CHANGELOG,
|
100
|
+
# because they don't render well as markdown on the Release page
|
101
|
+
#
|
102
|
+
echo "$annotation" | tail -n +2 | \
|
103
|
+
perl -pe 'BEGIN{undef $/;} s/\n\* (Mon|Tue|Wed|Thu|Fri|Sat|Sun) .*?\n//smg;' > /tmp/annotation.body
|
104
|
+
|
105
|
+
- name: Create Release
|
106
|
+
uses: actions/create-release@v1
|
107
|
+
id: create_release
|
108
|
+
env:
|
109
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
110
|
+
with:
|
111
|
+
tag_name: ${{ github.ref }}
|
112
|
+
release_name: ${{ steps.tag-check.outputs.annotation_title }}
|
113
|
+
body_path: /tmp/annotation.body
|
114
|
+
draft: false
|
115
|
+
prerelease: false
|
116
|
+
|
117
|
+
deploy-rubygem:
|
118
|
+
name: Deploy RubyGem Release
|
119
|
+
needs: [ releng-checks ]
|
120
|
+
runs-on: ubuntu-18.04
|
121
|
+
env:
|
122
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
123
|
+
BUILD_COMMAND: ${{ needs.releng-checks.outputs.build_command }}
|
124
|
+
RELEASE_COMMAND: ${{ needs.releng-checks.outputs.release_command }}
|
125
|
+
steps:
|
126
|
+
- name: Checkout code
|
127
|
+
uses: actions/checkout@v2
|
128
|
+
with:
|
129
|
+
ref: ${{ github.ref }}
|
130
|
+
clean: true
|
131
|
+
- uses: ruby/setup-ruby@v1
|
132
|
+
with:
|
133
|
+
ruby-version: 2.5
|
134
|
+
bundler-cache: true
|
135
|
+
- name: Build RubyGem
|
136
|
+
run: '$BUILD_COMMAND'
|
137
|
+
|
138
|
+
- name: Release RubyGem
|
139
|
+
run: |
|
140
|
+
echo "Setting up gem credentials..."
|
141
|
+
mkdir -p ~/.gem
|
142
|
+
|
143
|
+
cat << EOF > ~/.gem/credentials
|
144
|
+
---
|
145
|
+
:rubygems_api_key: ${RUBYGEMS_API_KEY}
|
146
|
+
EOF
|
147
|
+
chmod 0600 ~/.gem/credentials
|
148
|
+
|
149
|
+
chmod -R go=u-w .
|
150
|
+
|
151
|
+
echo "Running '$RELEASE_COMMAND'..."
|
152
|
+
$RELEASE_COMMAND
|
data/.gitlab-ci.yml
CHANGED
@@ -1,11 +1,4 @@
|
|
1
1
|
# ------------------------------------------------------------------------------
|
2
|
-
# NOTICE: **This file is maintained with puppetsync**
|
3
|
-
#
|
4
|
-
# This file is updated automatically as part of a puppet module baseline.
|
5
|
-
#
|
6
|
-
# The next baseline sync will overwrite any local changes to everything above
|
7
|
-
# the line "# Repo-specific content"
|
8
|
-
# ------------------------------------------------------------------------------
|
9
2
|
# The testing matrix considers ruby/puppet versions supported by SIMP and PE:
|
10
3
|
#
|
11
4
|
# https://puppet.com/docs/pe/2019.8/component_versions_in_recent_pe_releases.html
|
@@ -216,28 +209,28 @@ variables:
|
|
216
209
|
# Puppet Versions
|
217
210
|
#-----------------------------------------------------------------------
|
218
211
|
|
219
|
-
.
|
212
|
+
.pup_5_x: &pup_5_x
|
220
213
|
image: 'ruby:2.4'
|
221
214
|
variables:
|
222
215
|
PUPPET_VERSION: '~> 5.0'
|
223
216
|
BEAKER_PUPPET_COLLECTION: 'puppet5'
|
224
217
|
MATRIX_RUBY_VERSION: '2.4'
|
225
218
|
|
226
|
-
.
|
219
|
+
.pup_6_x: &pup_6_x
|
227
220
|
image: 'ruby:2.5'
|
228
221
|
variables:
|
229
222
|
PUPPET_VERSION: '~> 6.0'
|
230
223
|
BEAKER_PUPPET_COLLECTION: 'puppet6'
|
231
224
|
MATRIX_RUBY_VERSION: '2.5'
|
232
225
|
|
233
|
-
.
|
226
|
+
.pup_6_pe: &pup_6_pe
|
234
227
|
image: 'ruby:2.5'
|
235
228
|
variables:
|
236
229
|
PUPPET_VERSION: '6.18.0'
|
237
230
|
BEAKER_PUPPET_COLLECTION: 'puppet6'
|
238
231
|
MATRIX_RUBY_VERSION: '2.5'
|
239
232
|
|
240
|
-
.
|
233
|
+
.pup_7_x: &pup_7_x
|
241
234
|
image: 'ruby:2.7'
|
242
235
|
variables:
|
243
236
|
PUPPET_VERSION: '~> 7.0'
|
@@ -280,24 +273,18 @@ variables:
|
|
280
273
|
# Unit Tests
|
281
274
|
#-----------------------------------------------------------------------
|
282
275
|
|
283
|
-
pup5-unit:
|
284
|
-
<<: *
|
276
|
+
pup5.x-unit:
|
277
|
+
<<: *pup_5_x
|
285
278
|
<<: *unit_tests
|
286
279
|
|
287
|
-
pup6-unit:
|
288
|
-
<<: *
|
280
|
+
pup6.x-unit:
|
281
|
+
<<: *pup_6_x
|
289
282
|
<<: *unit_tests
|
290
283
|
|
291
|
-
pup7-unit:
|
292
|
-
<<: *
|
284
|
+
pup7.x-unit:
|
285
|
+
<<: *pup_7_x
|
293
286
|
<<: *unit_tests
|
294
287
|
|
295
|
-
# ------------------------------------------------------------------------------
|
296
|
-
# NOTICE: **This file is maintained with puppetsync**
|
297
|
-
#
|
298
|
-
# Everything above the "Repo-specific content" comment will be overwritten by
|
299
|
-
# the next puppetsync.
|
300
|
-
# ------------------------------------------------------------------------------
|
301
288
|
|
302
289
|
# Repo-specific content
|
303
290
|
# ==============================================================================
|
@@ -305,20 +292,20 @@ pup7-unit:
|
|
305
292
|
#=======================================================================
|
306
293
|
# Packaging test
|
307
294
|
|
308
|
-
pup5-pkg:
|
309
|
-
<<: *
|
295
|
+
pup5.x-pkg:
|
296
|
+
<<: *pup_5_x
|
310
297
|
<<: *unit_tests
|
311
298
|
script:
|
312
299
|
'bundle exec rake pkg:gem'
|
313
300
|
|
314
|
-
pup6-pkg:
|
315
|
-
<<: *
|
301
|
+
pup6.x-pkg:
|
302
|
+
<<: *pup_6_x
|
316
303
|
<<: *unit_tests
|
317
304
|
script:
|
318
305
|
'bundle exec rake pkg:gem'
|
319
306
|
|
320
|
-
pup7-pkg:
|
321
|
-
<<: *
|
307
|
+
pup7.x-pkg:
|
308
|
+
<<: *pup_7_x
|
322
309
|
<<: *unit_tests
|
323
310
|
script:
|
324
311
|
'bundle exec rake pkg:gem'
|
@@ -326,49 +313,49 @@ pup7-pkg:
|
|
326
313
|
#=======================================================================
|
327
314
|
# Acceptance tests
|
328
315
|
default:
|
329
|
-
<<: *
|
316
|
+
<<: *pup_6_x
|
330
317
|
<<: *acceptance_base
|
331
318
|
script:
|
332
319
|
- bundle exec rake beaker:suites[default]
|
333
320
|
|
334
321
|
default-fips:
|
335
|
-
<<: *
|
322
|
+
<<: *pup_6_x
|
336
323
|
<<: *acceptance_base
|
337
324
|
script:
|
338
325
|
- BEAKER_fips=yes bundle exec rake beaker:suites[default]
|
339
326
|
|
340
327
|
fips_from_fixtures:
|
341
|
-
<<: *
|
328
|
+
<<: *pup_6_x
|
342
329
|
<<: *acceptance_base
|
343
330
|
script:
|
344
331
|
- bundle exec rake beaker:suites[fips_from_fixtures]
|
345
332
|
|
346
333
|
puppet5_collections:
|
347
|
-
<<: *
|
334
|
+
<<: *pup_5_x
|
348
335
|
<<: *acceptance_base
|
349
336
|
script:
|
350
337
|
- bundle exec rake beaker:suites[puppet_collections]
|
351
338
|
|
352
339
|
puppet6_collections:
|
353
|
-
<<: *
|
340
|
+
<<: *pup_6_x
|
354
341
|
<<: *acceptance_base
|
355
342
|
script:
|
356
343
|
- bundle exec rake beaker:suites[puppet_collections]
|
357
344
|
|
358
345
|
puppet7_collections:
|
359
|
-
<<: *
|
346
|
+
<<: *pup_7_x
|
360
347
|
<<: *acceptance_base
|
361
348
|
script:
|
362
349
|
- bundle exec rake beaker:suites[puppet_collections]
|
363
350
|
|
364
351
|
windows:
|
365
|
-
<<: *
|
352
|
+
<<: *pup_6_x
|
366
353
|
<<: *acceptance_base
|
367
354
|
script:
|
368
355
|
- bundle exec rake beaker:suites[windows]
|
369
356
|
|
370
357
|
snapshot:
|
371
|
-
<<: *
|
358
|
+
<<: *pup_6_x
|
372
359
|
<<: *acceptance_base
|
373
360
|
# This is prone to breakage in the underlying system
|
374
361
|
allow_failure: true
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
### 1.22.1 / 2021-03-01
|
2
|
+
* Fixed: enable_epel_on() now installs the correct EPEL repository
|
3
|
+
package on OracleLinux
|
4
|
+
|
5
|
+
### 1.22.0 / 2021-01-27
|
6
|
+
* Fixed:
|
7
|
+
* Ensure that the simp-crypto_policy module is installed when flipping to FIPS
|
8
|
+
mode
|
9
|
+
* Only attempt to install the simp repos once in case they are broken for some
|
10
|
+
reason
|
11
|
+
* Added:
|
12
|
+
* Documentation for all of the beaker environment variables
|
13
|
+
* set_simp_repo_release() for setting the release and release_type of the
|
14
|
+
public SIMP yum repos
|
15
|
+
* set_yum_opts_on() method for setting bulk yum config options
|
16
|
+
* set_yum_opt_on() method for setting singular yum config options
|
17
|
+
* install_package_unless_present_on() method
|
18
|
+
* Allow users to set repos to disable using an environment variable
|
19
|
+
* A total run time summary for beaker suites
|
20
|
+
|
1
21
|
### 1.21.4 / 2021-01-21
|
2
22
|
* Fixed:
|
3
23
|
* Reverted the use of OpenStruct due to issues with seralization
|
data/README.md
CHANGED
@@ -13,6 +13,8 @@ Methods to assist beaker acceptance tests for SIMP.
|
|
13
13
|
* [`rake beaker:suites`](#rake-beakersuites)
|
14
14
|
* [Suite Execution](#suite-execution)
|
15
15
|
* [Environment Variables](#environment-variables)
|
16
|
+
* [Beaker Management](#beaker-management)
|
17
|
+
* [Beaker Helpers Adjustments](#beaker-helpers-adjustments)
|
16
18
|
* [Global Suite Configuration](#global-suite-configuration)
|
17
19
|
* [Supported Config:](#supported-config)
|
18
20
|
* [Individual Suite Configuration](#individual-suite-configuration)
|
@@ -112,12 +114,68 @@ sensitive).
|
|
112
114
|
|
113
115
|
#### Environment Variables
|
114
116
|
|
115
|
-
|
117
|
+
##### Beaker Management
|
118
|
+
|
119
|
+
* BEAKER_suite_runall [yes|no]
|
116
120
|
* Run all Suites
|
117
121
|
|
118
|
-
* BEAKER_suite_basedir
|
122
|
+
* BEAKER_suite_basedir [String]
|
119
123
|
* The base directory where suites will be defined
|
120
|
-
* Default: spec/acceptance
|
124
|
+
* Default: `spec/acceptance`
|
125
|
+
|
126
|
+
##### Beaker Helpers Adjustments
|
127
|
+
|
128
|
+
* BEAKER_SIMP_parallel [yes|no]
|
129
|
+
* `yes` => Run simp-beaker-helpers methods on SUTs in parallel if possible
|
130
|
+
* `no` => Do not run methods in parallel
|
131
|
+
|
132
|
+
* BEAKER_docker_cmd [String]
|
133
|
+
* The specific command to use for performing `docker` operations
|
134
|
+
|
135
|
+
* BEAKER_helpers_verbose [yes|no]
|
136
|
+
* `yes` => Enable verbose output
|
137
|
+
* `no` => Do not enable verbose output
|
138
|
+
|
139
|
+
* BEAKER_copy_fixtures [yes|no]
|
140
|
+
* `yes` => Enable copying fixtures to the SUT
|
141
|
+
* `no` => Disable copying fixtures to the SUT
|
142
|
+
|
143
|
+
* BEAKER_use_fixtures_dir_for_modules [yes|no]
|
144
|
+
* `yes` => Pull fixtures directly from `spec/fixtures/modules`
|
145
|
+
* `no` => Ignore `spec/fixtures/modules` content
|
146
|
+
|
147
|
+
* BEAKER_stringify_facts [yes|no]
|
148
|
+
* `yes` => Enable fact stringification
|
149
|
+
|
150
|
+
* BEAKER_fips_module_version [String]
|
151
|
+
* The specific version of the FIPS module to install from the puppet forge
|
152
|
+
|
153
|
+
* BEAKER_RHSM_USER [String]
|
154
|
+
* The username for using with RHSM
|
155
|
+
|
156
|
+
* BEAKER_RHSM_PASS [String]
|
157
|
+
* The password for using with RHSM
|
158
|
+
|
159
|
+
* BEAKER_fips [yes|no]
|
160
|
+
* `yes` => Enable FIPS on the SUT
|
161
|
+
* `no` => Do not manage FIPS on the SUT (will not disable if enabled)
|
162
|
+
|
163
|
+
* BEAKER_no_fix_interfaces [Boolean]
|
164
|
+
* If present, will not try to fix the interfaces on the SUT
|
165
|
+
|
166
|
+
* BEAKER_SIMP_install_repos [yes|no]
|
167
|
+
* `yes` => Install the SIMP YUM repositories
|
168
|
+
* `no` => No not install the SIMP YUM repositories
|
169
|
+
|
170
|
+
* BEAKER_SIMP_disable_repos [String]
|
171
|
+
* Comma delimited list of YUM repositories to disable on the SUT
|
172
|
+
|
173
|
+
* BEAKER_SIMP_repo_release [String]
|
174
|
+
* The release of SIMP to target in the YUM repos (usually a number)
|
175
|
+
|
176
|
+
* BEAKER_SIMP_repo_release_type [String]
|
177
|
+
* The release type of SIMP to target in the YUM repos
|
178
|
+
* Something like `stable`, `rolling`, or `unstable`
|
121
179
|
|
122
180
|
#### Global Suite Configuration
|
123
181
|
|
@@ -406,7 +464,7 @@ might try to install packages before subscription manager is configured.
|
|
406
464
|
The version of InSpec to use when running inspec tests. Currently hard-coded to
|
407
465
|
`4.16.14` due to a bug introduced in `4.16.15`.
|
408
466
|
|
409
|
-
|
467
|
+
Set to 'latest' to use the latest available in the upstream repos.
|
410
468
|
|
411
469
|
## Examples
|
412
470
|
|
@@ -510,7 +568,7 @@ underlying OS configuration.
|
|
510
568
|
|
511
569
|
`Simp::BeakerHelpers::Snapshot.save(sut, '<name of snapshot>')` will save a
|
512
570
|
snapshot with the given name. If the snapshot already exists, it will be
|
513
|
-
|
571
|
+
forcibly overwritten.
|
514
572
|
|
515
573
|
|
516
574
|
##### Base Snapshots
|
data/lib/simp/beaker_helpers.rb
CHANGED
@@ -18,7 +18,53 @@ module Simp::BeakerHelpers
|
|
18
18
|
"simp-beaker-helpers-#{t}-#{$$}-#{rand(0x100000000).to_s(36)}.tmp"
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
# Sets a single YUM option in the form that yum-config-manager/dnf
|
22
|
+
# config-manager would expect.
|
23
|
+
#
|
24
|
+
# If not prefaced with a repository, the option will be applied globally.
|
25
|
+
#
|
26
|
+
# Has no effect if yum or dnf is not present.
|
27
|
+
def set_yum_opt_on(suts, key, value)
|
28
|
+
parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
|
29
|
+
block_on(suts, :run_in_parallel => parallel) do |sut|
|
30
|
+
repo,target = key.split('.')
|
31
|
+
|
32
|
+
unless target
|
33
|
+
key = "\\*.#{repo}"
|
34
|
+
end
|
35
|
+
|
36
|
+
command = nil
|
37
|
+
if !sut.which('dnf').empty?
|
38
|
+
install_package_unless_present_on(sut, 'dnf-plugins-core', :accept_all_exit_codes => true)
|
39
|
+
command = 'dnf config-manager'
|
40
|
+
elsif !sut.which('yum').empty?
|
41
|
+
command = 'yum-config-manager'
|
42
|
+
end
|
43
|
+
|
44
|
+
on(sut, %{#{command} --save --setopt=#{key}=#{value}}, :silent => true) if command
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Takes a hash of YUM options to set in the form that yum-config-manager/dnf
|
49
|
+
# config-manager would expect.
|
50
|
+
#
|
51
|
+
# If not prefaced with a repository, the option will be applied globally.
|
52
|
+
#
|
53
|
+
# Example:
|
54
|
+
# {
|
55
|
+
# 'skip_if_unavailable' => '1', # Applies globally
|
56
|
+
# 'foo.installonly_limit' => '5' # Applies only to the 'foo' repo
|
57
|
+
# }
|
58
|
+
def set_yum_opts_on(suts, yum_opts={})
|
59
|
+
parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
|
60
|
+
block_on(suts, :run_in_parallel => parallel) do |sut|
|
61
|
+
yum_opts.each_pair do |k,v|
|
62
|
+
set_yum_opt_on(sut, k, v)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def install_package_unless_present_on(suts, package_name, package_source=nil, opts={})
|
22
68
|
default_opts = {
|
23
69
|
max_retries: 3,
|
24
70
|
retry_interval: 10
|
@@ -28,19 +74,35 @@ module Simp::BeakerHelpers
|
|
28
74
|
block_on(suts, :run_in_parallel => parallel) do |sut|
|
29
75
|
package_source = package_name unless package_source
|
30
76
|
|
31
|
-
|
32
|
-
sut.
|
77
|
+
unless sut.check_for_package(package_name)
|
78
|
+
sut.install_package(
|
33
79
|
package_source,
|
34
80
|
'',
|
81
|
+
nil,
|
35
82
|
default_opts.merge(opts)
|
36
83
|
)
|
37
|
-
|
38
|
-
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def install_latest_package_on(suts, package_name, package_source=nil, opts={})
|
89
|
+
default_opts = {
|
90
|
+
max_retries: 3,
|
91
|
+
retry_interval: 10
|
92
|
+
}
|
93
|
+
|
94
|
+
parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
|
95
|
+
block_on(suts, :run_in_parallel => parallel) do |sut|
|
96
|
+
package_source = package_name unless package_source
|
97
|
+
|
98
|
+
if sut.check_for_package(package_name)
|
99
|
+
sut.upgrade_package(
|
39
100
|
package_source,
|
40
101
|
'',
|
41
|
-
nil,
|
42
102
|
default_opts.merge(opts)
|
43
103
|
)
|
104
|
+
else
|
105
|
+
install_package_unless_present_on(sut, package_name, package_source, opts)
|
44
106
|
end
|
45
107
|
end
|
46
108
|
end
|
@@ -434,13 +496,16 @@ module Simp::BeakerHelpers
|
|
434
496
|
|
435
497
|
fips_enable_modulepath = '--modulepath=/root/.beaker_fips/modules'
|
436
498
|
|
437
|
-
|
499
|
+
modules_to_install = {
|
500
|
+
'simp-fips' => ENV['BEAKER_fips_module_version'],
|
501
|
+
'simp-crypto_policy' => nil
|
502
|
+
}
|
438
503
|
|
439
|
-
|
440
|
-
module_install_cmd
|
504
|
+
modules_to_install.each_pair do |to_install, version|
|
505
|
+
module_install_cmd = "puppet module install #{to_install} --target-dir=/root/.beaker_fips/modules"
|
506
|
+
module_install_cmd += " --version #{version}" if version
|
507
|
+
on(sut, module_install_cmd)
|
441
508
|
end
|
442
|
-
|
443
|
-
on(sut, module_install_cmd)
|
444
509
|
end
|
445
510
|
|
446
511
|
# Work around Vagrant and cipher restrictions in EL8+
|
@@ -549,12 +614,13 @@ module Simp::BeakerHelpers
|
|
549
614
|
def enable_epel_on(suts)
|
550
615
|
parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
|
551
616
|
block_on(suts, :run_in_parallel => parallel) do |sut|
|
552
|
-
if ONLINE
|
617
|
+
if ONLINE
|
553
618
|
os_info = fact_on(sut, 'os')
|
554
619
|
os_maj_rel = os_info['release']['major']
|
555
620
|
|
556
621
|
# This is based on the official EPEL docs https://fedoraproject.org/wiki/EPEL
|
557
|
-
|
622
|
+
case os_info['name']
|
623
|
+
when 'RedHat','CentOS'
|
558
624
|
install_latest_package_on(
|
559
625
|
sut,
|
560
626
|
'epel-release',
|
@@ -580,7 +646,11 @@ module Simp::BeakerHelpers
|
|
580
646
|
on sut, %{dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled PowerTools}
|
581
647
|
end
|
582
648
|
end
|
649
|
+
when 'OracleLinux'
|
650
|
+
package_name = "oracle-epel-release-el#{os_maj_rel}"
|
651
|
+
install_latest_package_on(sut,package_name)
|
583
652
|
end
|
653
|
+
|
584
654
|
end
|
585
655
|
end
|
586
656
|
end
|
@@ -1397,49 +1467,79 @@ module Simp::BeakerHelpers
|
|
1397
1467
|
# * 'simp-community-postgres'
|
1398
1468
|
# * 'simp-community-puppet'
|
1399
1469
|
#
|
1400
|
-
|
1470
|
+
#
|
1471
|
+
# Environment Variables:
|
1472
|
+
# * BEAKER_SIMP_install_repos
|
1473
|
+
# * 'no' => disable the capability
|
1474
|
+
# * BEAKER_SIMP_disable_repos
|
1475
|
+
# * Comma delimited list of active yum repo names to disable
|
1476
|
+
def install_simp_repos(suts, disable = [])
|
1401
1477
|
# NOTE: Do *NOT* use puppet in this method since it may not be available yet
|
1402
1478
|
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1479
|
+
return if (ENV.fetch('SIMP_install_repos', 'yes') == 'no')
|
1480
|
+
|
1481
|
+
parallel = (ENV['BEAKER_SIMP_parallel'] == 'yes')
|
1482
|
+
block_on(suts, :run_in_parallel => parallel) do |sut|
|
1483
|
+
install_package_unless_present_on(sut, 'yum-utils')
|
1484
|
+
|
1485
|
+
install_package_unless_present_on(
|
1486
|
+
sut,
|
1487
|
+
'simp-release-community',
|
1488
|
+
"https://download.simp-project.com/simp-release-community.rpm",
|
1489
|
+
)
|
1409
1490
|
|
1410
|
-
|
1491
|
+
to_disable = disable.dup
|
1492
|
+
to_disable += ENV.fetch('BEAKER_SIMP_disable_repos', '').split(',').map(&:strip)
|
1411
1493
|
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1494
|
+
unless to_disable.empty?
|
1495
|
+
if to_disable.include?('simp')
|
1496
|
+
to_disable.delete('simp')
|
1497
|
+
to_disable << 'simp-community-simp'
|
1498
|
+
end
|
1417
1499
|
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1500
|
+
if to_disable.include?('simp_deps')
|
1501
|
+
to_disable.delete('simp_deps')
|
1502
|
+
to_disable << 'simp-community-epel'
|
1503
|
+
to_disable << 'simp-community-postgres'
|
1504
|
+
to_disable << 'simp-community-puppet'
|
1505
|
+
end
|
1424
1506
|
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1507
|
+
# NOTE: This --enablerepo enables the repos for listing and is inherited
|
1508
|
+
# from YUM. This does not actually "enable" the repos, that would require
|
1509
|
+
# the "--enable" option (from yum-config-manager) :-D.
|
1510
|
+
#
|
1511
|
+
# Note: Certain versions of EL8 do not dump by default and EL7 does not
|
1512
|
+
# have the '--dump' option.
|
1513
|
+
available_repos = on(sut, %{yum-config-manager --enablerepo="*" || yum-config-manager --enablerepo="*" --dump}).stdout.lines.grep(/\A\[(.+)\]\Z/){|x| $1}
|
1432
1514
|
|
1433
|
-
|
1515
|
+
invalid_repos = (to_disable - available_repos)
|
1434
1516
|
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1517
|
+
# Verify that the repos passed to disable are in the list of valid repos
|
1518
|
+
unless invalid_repos.empty?
|
1519
|
+
logger.warn(%{WARN: install_simp_repo - requested repos to disable do not exist on the target system '#{invalid_repos.join("', '")}'.})
|
1520
|
+
end
|
1439
1521
|
|
1440
|
-
|
1441
|
-
|
1522
|
+
(to_disable - invalid_repos).each do |repo|
|
1523
|
+
on(sut, %{yum-config-manager --disable "#{repo}"})
|
1524
|
+
end
|
1442
1525
|
end
|
1443
1526
|
end
|
1527
|
+
|
1528
|
+
set_yum_opts_on(suts, {'simp*.skip_if_unavailable' => '1' })
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
# Set the release and release type of the SIMP yum repos
|
1532
|
+
#
|
1533
|
+
# Environment variables may be used to set either one
|
1534
|
+
# * BEAKER_SIMP_repo_release => The actual release (version number)
|
1535
|
+
# * BEAKER_SIMP_repo_release_type => The type of release (stable, unstable, rolling, etc...)
|
1536
|
+
def set_simp_repo_release(sut, simp_release_type='stable', simp_release='6')
|
1537
|
+
simp_release = ENV.fetch('BEAKER_SIMP_repo_release', simp_release)
|
1538
|
+
simp_release_type = ENV.fetch('BEAKER_SIMP_repo_release_type', simp_release_type)
|
1539
|
+
|
1540
|
+
simp_release_type = 'releases' if (simp_release_type == 'stable')
|
1541
|
+
|
1542
|
+
create_remote_file(sut, '/etc/yum/vars/simprelease', simp_release)
|
1543
|
+
create_remote_file(sut, '/etc/yum/vars/simpreleasetype', simp_release_type)
|
1444
1544
|
end
|
1445
1545
|
end
|
data/lib/simp/rake/beaker.rb
CHANGED
@@ -196,6 +196,7 @@ module Simp::Rake
|
|
196
196
|
default_suite = ordered_suites.delete('default')
|
197
197
|
ordered_suites.unshift(default_suite) if default_suite
|
198
198
|
|
199
|
+
suite_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
199
200
|
ordered_suites.each do |ste|
|
200
201
|
|
201
202
|
next unless (suites[ste]['default_run'] == true)
|
@@ -255,6 +256,11 @@ module Simp::Rake
|
|
255
256
|
$stdout.puts("\n\n=== Suite '#{name}' Complete ===\n\n")
|
256
257
|
end
|
257
258
|
end
|
259
|
+
suite_end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
260
|
+
|
261
|
+
suite_run_time = ((suite_end_time - suite_start_time)/60).round(2)
|
262
|
+
|
263
|
+
$stdout.puts("== Total Runtime: #{suite_run_time} minutes ==\n\n")
|
258
264
|
|
259
265
|
unless failures.keys.empty?
|
260
266
|
$stdout.puts("The following tests had failures:")
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper_acceptance'
|
2
2
|
|
3
3
|
hosts.each do |host|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
4
|
+
expect_failures = false
|
5
|
+
if hosts_with_role(hosts, 'el8').include?(host)
|
6
|
+
expect_failures = true
|
7
|
+
end
|
9
8
|
|
9
|
+
describe '#install_simp_repos' do
|
10
10
|
it 'should install yum utils' do
|
11
11
|
host.install_package('yum-utils')
|
12
12
|
end
|
@@ -21,6 +21,18 @@ hosts.each do |host|
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
context 'when targeting a release type' do
|
25
|
+
it 'adjusts the SIMP release target' do
|
26
|
+
set_simp_repo_release(host, 'rolling')
|
27
|
+
expect(file_content_on(host, '/etc/yum/vars/simpreleasetype').strip).to eq('rolling')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'lists the simp rpm' do
|
31
|
+
skip "#{host} is not supported yet" if expect_failures
|
32
|
+
on(host, 'yum list simp')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
24
36
|
context 'when passed a disabled list ' do
|
25
37
|
before(:all) { install_simp_repos(host, ['simp-community-simp'] ) }
|
26
38
|
|
@@ -18,6 +18,7 @@ new_fixtures = {
|
|
18
18
|
}
|
19
19
|
}
|
20
20
|
|
21
|
+
new_fixtures['fixtures']['repositories']['crypto_policy'] = 'https://github.com/simp/pupmod-simp-crypto_policy'
|
21
22
|
new_fixtures['fixtures']['repositories']['fips'] = 'https://github.com/simp/pupmod-simp-fips'
|
22
23
|
new_fixtures['fixtures']['repositories']['augeasproviders_core'] = 'https://github.com/simp/augeasproviders_core'
|
23
24
|
new_fixtures['fixtures']['repositories']['augeasproviders_grub'] = 'https://github.com/simp/augeasproviders_grub'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simp-beaker-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.22.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Tessmer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-01
|
12
|
+
date: 2021-03-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: beaker
|
@@ -163,11 +163,14 @@ extra_rdoc_files: []
|
|
163
163
|
files:
|
164
164
|
- ".fips_fixtures"
|
165
165
|
- ".fixtures.yml"
|
166
|
+
- ".github/workflows/pr_glci.yml"
|
167
|
+
- ".github/workflows/pr_glci_cleanup.yml"
|
168
|
+
- ".github/workflows/pr_glci_manual.yml"
|
169
|
+
- ".github/workflows/tag_deploy_rubygem.yml"
|
166
170
|
- ".gitignore"
|
167
171
|
- ".gitlab-ci.yml"
|
168
172
|
- ".rspec"
|
169
173
|
- ".rubocop.yml"
|
170
|
-
- ".travis.yml"
|
171
174
|
- CHANGELOG.md
|
172
175
|
- Gemfile
|
173
176
|
- LICENSE
|
data/.travis.yml
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
---
|
2
|
-
language: shell
|
3
|
-
notifications:
|
4
|
-
email: false
|
5
|
-
stages:
|
6
|
-
- name: deploy
|
7
|
-
if: 'tag IS present'
|
8
|
-
|
9
|
-
### Testing on Travis CI is indefinitely disabled
|
10
|
-
###
|
11
|
-
### See:
|
12
|
-
### * https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing
|
13
|
-
### * https://simp-project.atlassian.net/browse/SIMP-8703
|
14
|
-
jobs:
|
15
|
-
include:
|
16
|
-
- stage: deploy
|
17
|
-
script: skip
|
18
|
-
cache: bundler
|
19
|
-
before_install:
|
20
|
-
- rm Gemfile.lock || true
|
21
|
-
bundler_args: "--without development --path .vendor"
|
22
|
-
language: ruby
|
23
|
-
rvm: 2.4.5
|
24
|
-
before_deploy:
|
25
|
-
- bundle exec rake clobber
|
26
|
-
- "export GEM_VERSION=`ruby -r ./lib/simp/beaker_helpers/version.rb -e 'puts Simp::BeakerHelpers::VERSION'`"
|
27
|
-
- '[[ $TRAVIS_TAG =~ ^${GEM_VERSION}$ ]]'
|
28
|
-
deploy:
|
29
|
-
- provider: rubygems
|
30
|
-
gemspec: simp-beaker-helpers.gemspec
|
31
|
-
gem: simp-beaker-helpers
|
32
|
-
token:
|
33
|
-
secure: "AlnBx0dBSxn+S97n0h14ltKUOA+6v0bc7QZPIcwGJV9nnf1hKH3pf9La1TVknEx7XgpAcM9jusQJ7hBlqvSq8z8SFF0bZk1EgSRIKc1cuYPLiGyUM2O7+AFHyCy3iCnPvKeoQmE/BJb5O1dGnbmSbf4A0fqLxA7jiHG1j7z+cnmJB1i67wovDfl13TsOXyBfbespWBMMc0BKAw56FPs9XggAk2cNusS3hd5tqW1AZPT2/xwt+d8ngkmO96u8QcichYRFQ+w+XW4H0w935wNg/dWiskJlt7TIYVAh4Ko5s2DZKf52Tne8TugALSn0LhRatpp7sw1FTTpteCW8UqK8uwGC2hM4pZViAOv4P1YObz2IPOZPriBl+cCayJdMKnotkUJliAMnw5TLiSWKLou+S0Pdj2h3fJZWdOEwRPMzIVoJtsOHG3GdNcPL6f7iU0vP/wr6FeR3uWa+fA7NHRi2Du955O8JpogjdrW08ahcAEwhtI3A4mrA08wN09axsrwr093uDRm/5h4FHyAhExJ0YiA/6kcPpUvILcLStyHe0RQDICQMdsQo2DSbnL65w3QjFa2fML2Shf9cRwX06+ia2BxozWzFD/6p3RiRtPxphnbFiUdjYSGWcwCcUgbJx9SW04lSSxOhpyItuXgxZqiybkzstXd6riu5zwg1R8TWk34="
|
34
|
-
on:
|
35
|
-
tags: true
|
36
|
-
condition: "($SKIP_PUBLISH != true)"
|
37
|
-
- provider: releases
|
38
|
-
token:
|
39
|
-
secure: "I41p4aqjkrNDHJhZ5gWC4gzn7BVwEYRm5Q3PAxQRSIUDB/QTVgNqZx8YptkuIvSGpw8kIywyZg3NKdzGUO8aJJ0NlXapL7e9qQIigkYhdaCZjZFG5zIxdOFs4sVoz/6vnQT9JIcGWy7uS5xiNOulGvfEWU78+e+I9yPdT74RApve5VAVT/km5lV5ldRnwwehLnTx+volUlnOD8rwfizoVLqFTrfRfr4cVMF605UYyaiVxHF50hywFRZoAdVcMEhlLQnQXfz/ZsLMJLJm9eCpjQ989N0oX6theSLCcv7QtHcWMXydjWMcpuTfBZSFrwUVbC23uMOKTJVEWq5LMG3m2L6hP3//2gvUzGhOVLvoGuC+erboB7QoXdcoOgXY+dTZPMcPBxpArdDLWVQSLTvPs05QzpaUdRLVMC/kD1d1EudlEicgkNgNDBhBn3089nVmvKndbKLvj+23a5AQVVbs+8C0x+SJvTc9N2N+bmuH7jIJPrEvWK4xwcQa+g2M/EBv05jaEdSErlVa6B6UKCH0Lea9rpy1se9vn5OzpaaMCCJIpcpQqHDjo0PMAQXBSbqjKcBei6lR5fIFl5UO9gWP1v8PGPuCzGTBivQ92XlgV1TWXmdbJHwIuSbJx3Ali7Wp19RR4E4uHC+TPFssvgkh9ZLkORnWWS35wzzU1LkwWx0="
|
40
|
-
on:
|
41
|
-
tags: true
|
42
|
-
condition: "($SKIP_PUBLISH != true)"
|