-
Notifications
You must be signed in to change notification settings - Fork 113
312 lines (274 loc) · 12.6 KB
/
build.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
name: build
on:
workflow_dispatch:
inputs:
build_boxes:
type: choice
description: Build box name
default: "all"
options:
- "all"
- "my_windows-10-enterprise-x64-eval"
- "ubuntu-18.04-server-amd64"
- "ubuntu-20.04-desktop-amd64"
- "ubuntu-20.04-server-amd64"
- "windows-10-enterprise-x64-eval"
- "windows-server-2019-standard-x64-eval"
- "windows-server-2022-standard-x64-eval"
required: false
build_box_providers:
type: choice
description: Packer provider
default: "all"
options:
- "all"
- "libvirt"
- "virtualbox"
required: false
PACKER_LOG:
type: choice
description: PACKER_LOG (0, 1)
default: "0"
options:
- "0"
- "1"
required: false
ANSIBLE_DEBUG:
type: choice
description: ANSIBLE_DEBUG (true, false)
options:
- "false"
- "true"
required: false
VAGRANT_LOG:
type: choice
description: VAGRANT_LOG (debug, info, warn)
default: "warn"
options:
- "warn"
- "info"
- "debug"
required: false
build_upload:
type: choice
description: Upload release to Vagrant Cloud
options:
- "false"
- "true"
required: false
schedule:
- cron: "0 1 1 * *"
env:
PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PACKER_IMAGES_OUTPUT_DIR: /var/tmp/packer-templates-images
PACKER_CACHE_DIR: /var/tmp/packer_cache
LOGDIR: /var/tmp/packer-templates-logs
VAGRANT_CLOUD_USER: peru
VAGRANT_CLOUD_TOKEN: ${{ secrets.VAGRANT_CLOUD_TOKEN }}
# Needed for Packer when calling ansible (https://github.com/ansible/ansible/issues/32499)
OBJC_DISABLE_INITIALIZE_FORK_SAFETY: YES
# Note: windows-server-2016-standard-x64-eval was disabled because it take more than 6 hour to build the image - which is above the GH Action limit
BUILD_BOX_LIST: |
(
"my_windows-10-enterprise-x64-eval"
"ubuntu-18.04-server-amd64"
"ubuntu-20.04-desktop-amd64"
"ubuntu-20.04-server-amd64"
"windows-10-enterprise-x64-eval"
"windows-server-2019-standard-x64-eval"
"windows-server-2022-standard-x64-eval"
)
BUILD_BOX_PROVIDER_LIST: |
(
"libvirt"
"virtualbox"
)
permissions: read-all
jobs:
generate-matrix:
name: "Generate matrix"
runs-on: ubuntu-latest
outputs:
MATRIX: ${{ steps.set-matrix.outputs.MATRIX }}
steps:
- name: Get Matrix Builds
id: set-matrix
run: |
set -euxo pipefail
if [[ "${{ github.event.inputs.build_boxes }}" = "all" || "${{ github.event_name }}" == 'schedule' ]]; then
declare -a BUILD_BOXES=${{ env.BUILD_BOX_LIST }}
else
declare -a BUILD_BOXES=( "${{ github.event.inputs.build_boxes }}" )
fi
if [[ "${{ github.event.inputs.build_box_providers }}" = "all" || "${{ github.event_name }}" == 'schedule' ]]; then
declare -a BUILD_BOX_PROVIDERS=${{ env.BUILD_BOX_PROVIDER_LIST }}
else
declare -a BUILD_BOX_PROVIDERS=( "${{ github.event.inputs.build_box_providers }}" )
fi
for BUILD_BOX in "${BUILD_BOXES[@]}" ; do
NAME="${BUILD_BOX}"
for BUILD_BOX_PROVIDER in "${BUILD_BOX_PROVIDERS[@]}" ; do
PACKER_VAGRANT_PROVIDER="${BUILD_BOX_PROVIDER}"
# Check if the boxes (virtualbox/libvirt) with the same git hash already exists
if curl -s "https://app.vagrantup.com/${VAGRANT_CLOUD_USER}/boxes/${NAME}" | grep -q "Not found" ; then
CURRENT_VERSION_DESCRIPTION_MARKDOWN="Box doesn't exist"
else
CURRENT_VERSION_DESCRIPTION_MARKDOWN="$(curl -L --silent "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq '.current_version.version as $current_version | .versions[] | select (.version == $current_version) .description_markdown')"
fi
if [[ "${CURRENT_VERSION_DESCRIPTION_MARKDOWN}" =~ ${GITHUB_SHA} ]] ; then
echo "*** Git hash \"${GITHUB_SHA}\" found in current markdown description"
# Skip build if the box already exists
CURRENT_VERSION_PROVIDER_URL="$(curl -L --silent "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq -r ".current_version.version as \$current_version | .versions[] | select (.version == \$current_version) .providers[] | select (.name == \"${PACKER_VAGRANT_PROVIDER}\") .download_url")"
if [ -n "${CURRENT_VERSION_PROVIDER_URL}" ]; then
echo "*** Found already build image \"${BUILD_BOX}-${PACKER_VAGRANT_PROVIDER}\" with hash \"${GITHUB_SHA}\": ${CURRENT_VERSION_PROVIDER_URL}"
echo "*** This build will be skipped..."
else
# Set BOX_VERSION variable from existing provider (if exists) or from "date"
BOX_VERSION="$(curl -L --silent "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq -r ".current_version.version")"
echo "*** Using previously defined box version \"${BOX_VERSION}\", because there is already builded box with git hash \"${GITHUB_SHA}\""
BUILDS_MATRIX+=("${BUILD_BOX}-${PACKER_VAGRANT_PROVIDER}@${BOX_VERSION}")
fi
else
BOX_VERSION="$(date +%Y%m%d).01"
echo "*** Using new box version based on current date: ${BOX_VERSION}"
BUILDS_MATRIX+=("${BUILD_BOX}-${PACKER_VAGRANT_PROVIDER}@${BOX_VERSION}")
fi
done
done
jq --compact-output --null-input '$ARGS.positional' --args "${BUILDS_MATRIX[@]}"
echo "MATRIX=$( jq --compact-output --null-input '$ARGS.positional' --args "${BUILDS_MATRIX[@]}" )" | tee -a "${GITHUB_OUTPUT}"
build-boxes:
name: "*"
runs-on: macos-11
needs: generate-matrix
if: ${{ needs.generate-matrix.outputs.MATRIX != '[]' && needs.generate-matrix.outputs.MATRIX != '' }}
concurrency:
group: build-boxes-${{ matrix.stage }}
strategy:
# Do not cancel matrix jobs if one of them fails
fail-fast: false
matrix:
stage: ${{ fromJSON(needs.generate-matrix.outputs.MATRIX) }}
steps:
- name: Set PACKER_LOG, ANSIBLE_DEBUG, VAGRANT_LOG variables when using workflow_dispatch
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
set -euo pipefail
cat << EOF | tee -a "${GITHUB_ENV}"
PACKER_LOG=${{ github.event.inputs.PACKER_LOG }}
ANSIBLE_DEBUG=${{ github.event.inputs.ANSIBLE_DEBUG }}
VAGRANT_LOG=${{ github.event.inputs.VAGRANT_LOG }}
EOF
- name: Set global environment variables like BOX_VERSION, BUILD, NAME, PACKER_VAGRANT_PROVIDER
run: |
set -euo pipefail
STAGE="${{ matrix.stage }}"
echo "*** STAGE: ${STAGE}"
# shellcheck disable=SC2001
cat << EOF | tee -a "${GITHUB_ENV}"
BOX_VERSION=${STAGE##*@}
BUILD=${STAGE%@*}
NAME=${STAGE%-*}
PACKER_VAGRANT_PROVIDER=$(echo "${STAGE}" | sed 's/.*-\([^@]*\).*/\1/')
EOF
- uses: actions/checkout@v4
with:
submodules: true
- name: Install packages
run: |
set -euxo pipefail
brew install ansible bash coreutils gnu-sed jq packer hudochenkov/sshpass/sshpass hashicorp/tap/hashicorp-vagrant
if [[ "${PACKER_VAGRANT_PROVIDER}" = "libvirt" ]]; then
brew install qemu xorriso
qemu-system-x86_64 --version
fi
if [[ "${PACKER_VAGRANT_PROVIDER}" = "virtualbox" ]]; then
brew install virtualbox
vboxmanage --version
fi
packer plugins install github.com/hashicorp/ansible
packer plugins install github.com/hashicorp/qemu
packer plugins install github.com/hashicorp/vagrant
packer plugins install github.com/hashicorp/virtualbox
vagrant --version
packer --version
ansible --version
if [[ "${BUILD}" =~ windows ]]; then
# renovate: datasource=pypi depName=pywinrm
PYWINRM_VERSION="0.4.3"
pip3 install pywinrm=="${PYWINRM_VERSION}"
ansible-galaxy collection install --force -r ansible/requirements.yml
fi
echo "/usr/local/bin:/usr/local/opt/gnu-sed/libexec/gnubin:/usr/local/opt/coreutils/libexec/gnubin" >> "${GITHUB_PATH}"
# Remove unused packages to save some disk space
rm -rf /Users/runner/Library/Developer /Users/runner/Library/Android /Users/runner/hostedtoolcache /Users/runner/.dotnet
# Used by mxschmitt/action-tmate
touch continue
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
# with:
# limit-access-to-actor: true
- name: Build image
id: build_image
run: |
./build.sh "${BUILD}"
- name: Upload logs to GitHub artifact store in case of VirtualBox failure
uses: actions/upload-artifact@v3
if: ${{ always() && contains(matrix.stage, 'virtualbox') }}
with:
name: ${{ matrix.stage }}
path: ${{ env.LOGDIR }}/*
retention-days: 3
- name: Check the created box image
run: |
if [[ "${PACKER_VAGRANT_PROVIDER}" = "virtualbox" ]] ; then
./vagrant_init_destroy_boxes.sh "${PACKER_IMAGES_OUTPUT_DIR}/${BUILD}.box"
else
echo "*** Skipping the checks..."
fi
- name: Upload box to Vagrant Cloud
if: ${{ github.event_name == 'schedule' || github.event.inputs.build_upload == 'true' }}
run: |
./upload_box_to_vagrantcloud.sh "${VAGRANT_CLOUD_USER}@${PACKER_IMAGES_OUTPUT_DIR}/${BUILD}.box"
clean_check_versions:
needs: build-boxes
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Remove old versions
run: |
set -euxo pipefail
declare -a BUILD_BOXES=${{ env.BUILD_BOX_LIST }}
for NAME in "${BUILD_BOXES[@]}"; do
while read -r VERSION ; do
echo "*** Removing box version: https://vagrantcloud.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}/version/${VERSION}"
curl -s "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}/version/${VERSION}" -X DELETE -d "access_token=${VAGRANT_CLOUD_TOKEN}" -o /dev/null
done < <( curl -s "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq -r '.current_version.version as $current_version | .versions[] | select (.version != $current_version) .version' )
# Verify if current version of the box has both boxes (virtualbox + libvirt)
CURRENT_VERSION_PROVIDERS=$(curl -s "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}"| jq -r ".current_version.providers|length")
if [[ ${CURRENT_VERSION_PROVIDERS} -ne 2 ]]; then
echo "*** Current version of ${VAGRANT_CLOUD_USER}/${NAME} does not contain both box versions (virtualbox + libvirt) !"
continue
fi
done
- name: Verify if the boxes are available on the Vagrant Cloud
run: |
set -euxo pipefail
declare -a BUILD_BOXES=${{ env.BUILD_BOX_LIST }}
declare -a BUILD_BOX_PROVIDERS=${{ env.BUILD_BOX_PROVIDER_LIST }}
for NAME in "${BUILD_BOXES[@]}"; do
for VAGRANT_PROVIDER in "${BUILD_BOX_PROVIDERS[@]}"; do
CURRENT_VERSION=$(curl -s "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq -r ".current_version.version")
CHECKSUM=$(curl -s "https://app.vagrantup.com/api/v1/box/${VAGRANT_CLOUD_USER}/${NAME}" | jq -r ".current_version.providers[] | select (.name == \"${VAGRANT_PROVIDER}\") .checksum")
URL="https://app.vagrantup.com/${VAGRANT_CLOUD_USER}/boxes/${NAME}/versions/${CURRENT_VERSION}/providers/${VAGRANT_PROVIDER}.box"
echo "*** ${URL} | ${CHECKSUM}"
if ! curl -L --fail --silent --head --output /dev/null "${URL}"; then
echo "* URL \"${URL}\" is not accessible !"
exit 1
fi
if [ "$(curl -s "https://app.vagrantup.com/${VAGRANT_CLOUD_USER}/boxes/${NAME}" | jq '.versions | length')" != "1" ]; then
echo "* Too many versions for: https://app.vagrantup.com/${VAGRANT_CLOUD_USER}/boxes/${NAME} !"
exit 2
fi
done
done