Skip to content

Commit 72c9554

Browse files
committed
feat(ci): add unified "Vagrant: Build, Test and Publish" workflow
Single workflow_dispatch that builds the Vagrant boxes with Packer, runs the `vagrant up` smoke test (shared-steps, gated by run_test), and publishes each box to the HCP Vagrant Registry - all on the same runner. The publish stage runs in-job on the locally-built .box (no S3 round-trip) and is gated by a new release_to_hcp input (default true). Publishes are serialized per box via a job-level concurrency group keyed on the box (matrix.variant): all providers of the same box+version (libvirt / virtualbox / vmware) publish one at a time since they target the same HCP box version, while different boxes (e.g. 10 and 10-v2) run in parallel. On a build-only run (release_to_hcp=false) the group also includes the provider so legs stay fully parallel. The publish logic lives in a new vagrant-publish-steps composite, adapted from vagrant-publish.yml minus dry-run: it sources the box from the local file, and installs the hcp CLI OS-aware (apt on the Ubuntu libvirt/ virtualbox legs, dnf/HashiCorp RPM repo on the EL9 vmware leg; vagrant is already present on every build runner). The standalone vagrant-publish.yml is left unchanged. Inputs are vagrant-build.yml's plus release_to_hcp; dry-run-mode is omitted.
1 parent aeb69ac commit 72c9554

2 files changed

Lines changed: 580 additions & 0 deletions

File tree

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
name: "Vagrant box publish steps"
2+
description: >
3+
Publish a locally-built AlmaLinux Vagrant .box to the HCP Vagrant
4+
Registry from the build runner: parse the box filename, install the hcp
5+
CLI (apt on Ubuntu, dnf/HashiCorp RPM repo on EL9 - vagrant itself is
6+
already present on every build runner), and run `vagrant cloud publish`.
7+
Adapted from the publish steps of .github/workflows/vagrant-publish.yml,
8+
minus dry-run, and sourcing the box from a local file instead of a URL.
9+
10+
inputs:
11+
image_file:
12+
description: "Path to the locally-built .box file"
13+
required: true
14+
image_url:
15+
description: "Public URL of the box (cosmetic, for the summary / notification link)"
16+
required: false
17+
default: ''
18+
notify_mattermost:
19+
description: "Send notification to Mattermost (true/false)"
20+
required: true
21+
default: 'true'
22+
HCP_CLIENT_ID:
23+
description: "HCP service-principal client ID"
24+
required: true
25+
HCP_CLIENT_SECRET:
26+
description: "HCP service-principal client secret"
27+
required: true
28+
HCP_ORG:
29+
description: "HCP Vagrant Registry organization"
30+
required: true
31+
MATTERMOST_WEBHOOK_URL:
32+
description: "Mattermost webhook URL"
33+
required: false
34+
default: ''
35+
MATTERMOST_CHANNEL:
36+
description: "Mattermost channel"
37+
required: false
38+
default: ''
39+
40+
runs:
41+
using: composite
42+
steps:
43+
- name: Prepare environment
44+
shell: bash
45+
env:
46+
IMAGE_FILE: ${{ inputs.image_file }}
47+
run: |
48+
# Parse the box filename to derive the HCP box name, provider,
49+
# version, and architecture (same logic as vagrant-publish.yml).
50+
image_file=$(basename "${IMAGE_FILE}")
51+
52+
# Regex for the modern and "Kitten" filename formats.
53+
REGEX_MODERN="^AlmaLinux-(Kitten|[0-9]+)-Vagrant-([a-z]+)-([0-9\.]+)-([0-9\.]+)\.(aarch64|x86_64)(_v2)?\.box$"
54+
55+
# Regex for the legacy (AlmaLinux 8) filename format.
56+
REGEX_LEGACY="^AlmaLinux-([0-9]+)-Vagrant-([0-9\.]+)-([0-9]+)\.(aarch64|x86_64)(_v2)?\.(.+)\.box$"
57+
58+
if [[ "$image_file" =~ $REGEX_MODERN ]]; then
59+
major_or_kitten="${BASH_REMATCH[1]}"
60+
provider="${BASH_REMATCH[2]}"
61+
release_version="${BASH_REMATCH[3]}"
62+
date_stamp="${BASH_REMATCH[4]}"
63+
architecture="${BASH_REMATCH[5]}"
64+
65+
if [[ "$major_or_kitten" == "Kitten" ]]; then
66+
major_version="10" # Kitten is based on version 10
67+
kitten_suffix="-kitten"
68+
else
69+
major_version="$major_or_kitten"
70+
# For non-Kitten files, remove the trailing .<digit> from the date stamp.
71+
date_stamp="${date_stamp%.*}"
72+
fi
73+
74+
if [[ -n "${BASH_REMATCH[6]}" ]]; then
75+
is_v2_suffix="-x86_64_v2"
76+
fi
77+
78+
elif [[ "$image_file" =~ $REGEX_LEGACY ]]; then
79+
major_version="${BASH_REMATCH[1]}"
80+
release_version="${BASH_REMATCH[2]}"
81+
date_stamp="${BASH_REMATCH[3]}"
82+
architecture="${BASH_REMATCH[4]}"
83+
provider="${BASH_REMATCH[6]}"
84+
85+
if [[ -n "${BASH_REMATCH[5]}" ]]; then
86+
is_v2_suffix="-x86_64_v2"
87+
fi
88+
89+
else
90+
echo "[Error]: No pattern matched for '$image_file'" && exit 1
91+
fi
92+
93+
# Remap "vmware" to the correct Vagrant provider name "vmware_desktop"
94+
if [[ "$provider" == "vmware" ]]; then
95+
provider="vmware_desktop"
96+
fi
97+
98+
# Construct the final box-name version string
99+
version_major="${major_version}${kitten_suffix}${is_v2_suffix}"
100+
101+
# AlmaLinux distro release string
102+
[[ $version_major == *kitten* ]] && release_string="AlmaLinux OS Kitten $major_version $architecture" \
103+
|| release_string="AlmaLinux OS $major_version $architecture"
104+
105+
{
106+
echo "version_major=${version_major}"
107+
echo "vagrant_provider=${provider}"
108+
echo "architecture=${architecture}"
109+
echo "release_version=${release_version}"
110+
echo "release_string=${release_string}"
111+
echo "date_stamp=${date_stamp}"
112+
echo "image_file=${image_file}"
113+
} >> "$GITHUB_ENV"
114+
115+
- name: Install hcp (and vagrant if missing)
116+
shell: bash
117+
run: |
118+
# vagrant is already present on the build runner; install the hcp
119+
# CLI OS-aware (apt on Ubuntu legs, dnf on the EL9 vmware leg).
120+
if command -v apt-get >/dev/null 2>&1; then
121+
ubuntu_codename="$(lsb_release -cs)"
122+
sudo rm -f /usr/share/keyrings/hashicorp-archive-keyring.gpg
123+
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
124+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com ${ubuntu_codename} main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
125+
sudo apt-get -y update
126+
sudo apt-get -y install hcp
127+
command -v vagrant >/dev/null 2>&1 || sudo apt-get -y install vagrant
128+
elif command -v dnf >/dev/null 2>&1; then
129+
sudo dnf install -y dnf-plugins-core
130+
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
131+
if ! sudo dnf install -y hcp; then
132+
# hcp may not be in the RPM repo on all EL9 mirrors; fall back to
133+
# the released binary.
134+
echo "[Info] hcp not available via dnf, downloading the released binary"
135+
sudo dnf install -y jq unzip
136+
ver=$(curl -fsSL https://api.releases.hashicorp.com/v1/releases/hcp/latest | jq -r .version)
137+
curl -fsSL -o /tmp/hcp.zip "https://releases.hashicorp.com/hcp/${ver}/hcp_${ver}_linux_amd64.zip"
138+
sudo unzip -o /tmp/hcp.zip hcp -d /usr/local/bin/
139+
fi
140+
command -v vagrant >/dev/null 2>&1 || sudo dnf install -y vagrant
141+
else
142+
echo "[Error] no supported package manager (apt-get / dnf) on this runner"
143+
exit 1
144+
fi
145+
146+
hcp version || true
147+
vagrant --version
148+
149+
- name: Publish the box
150+
shell: bash
151+
env:
152+
IMAGE_FILE: ${{ inputs.image_file }}
153+
HCP_CLIENT_ID: ${{ inputs.HCP_CLIENT_ID }}
154+
HCP_CLIENT_SECRET: ${{ inputs.HCP_CLIENT_SECRET }}
155+
HCP_ORG: ${{ inputs.HCP_ORG }}
156+
run: |
157+
# Publish the locally-built box to the HCP Vagrant Registry.
158+
# The lowercase fields below are populated by the "Prepare environment"
159+
# step via $GITHUB_ENV and read here as ${{ env.* }} (same style as
160+
# vagrant-publish.yml); checksum/arch are local to this script.
161+
BOX_DIR=$(dirname "${IMAGE_FILE}")
162+
cd "${BOX_DIR}"
163+
164+
[ "${{ env.architecture }}" = "x86_64" ] && arch=amd64
165+
[ "${{ env.architecture }}" = "aarch64" ] && arch=arm64
166+
167+
checksum="$(sha256sum "${{ env.image_file }}" | awk '{ print $1 }')"
168+
echo "[Debug] provider=${{ env.vagrant_provider }} box_name=${{ env.version_major }} checksum=${checksum} image_file=${{ env.image_file }}"
169+
170+
hcp auth login --client-id="${HCP_CLIENT_ID}" --client-secret="${HCP_CLIENT_SECRET}"
171+
VAGRANT_CLOUD_TOKEN="$(hcp auth print-access-token)"
172+
export VAGRANT_CLOUD_TOKEN
173+
174+
vagrant cloud publish \
175+
-C sha256 \
176+
-c "${checksum}" \
177+
--release \
178+
-a "${arch}" \
179+
--direct-upload \
180+
--debug \
181+
-f \
182+
"${HCP_ORG}/${{ env.version_major }}" \
183+
"${{ env.release_version }}.${{ env.date_stamp }}" \
184+
"${{ env.vagrant_provider }}" \
185+
"${{ env.image_file }}"
186+
187+
- name: The job summary
188+
uses: actions/github-script@v8
189+
env:
190+
HCP_ORG: ${{ inputs.HCP_ORG }}
191+
with:
192+
result-encoding: string
193+
script: |
194+
core.summary
195+
.addRaw('**${{ env.release_string }}** Vagrant box cloud publishing\n')
196+
.addRaw('Vagrant box for **${{ env.vagrant_provider }}** version: `${{ env.release_version }}.${{ env.date_stamp }}`\n')
197+
.addRaw('The box name: ')
198+
.addLink('${{ env.HCP_ORG }}/${{ env.version_major }}', 'https://portal.cloud.hashicorp.com/vagrant/discover/${{ env.HCP_ORG }}/${{ env.version_major }}/versions/${{ env.release_version }}.${{ env.date_stamp }}')
199+
.addRaw('Published to the Cloud: ✅')
200+
.write()
201+
202+
- name: Send notification to Mattermost
203+
uses: mattermost/action-mattermost-notify@master
204+
if: inputs.notify_mattermost == 'true' && inputs.MATTERMOST_WEBHOOK_URL != ''
205+
with:
206+
MATTERMOST_WEBHOOK_URL: ${{ inputs.MATTERMOST_WEBHOOK_URL }}
207+
MATTERMOST_CHANNEL: ${{ inputs.MATTERMOST_CHANNEL }}
208+
MATTERMOST_USERNAME: ${{ github.triggering_actor }}
209+
TEXT: |
210+
:almalinux: **${{ env.release_string }}** Vagrant box cloud publishing, by the GitHub [Action](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
211+
212+
Vagrant box for **${{ env.vagrant_provider }}** version: `${{ env.release_version }}.${{ env.date_stamp }}`
213+
214+
The box name: [${{ inputs.HCP_ORG }}/${{ env.version_major }}](https://portal.cloud.hashicorp.com/vagrant/discover/${{ inputs.HCP_ORG }}/${{ env.version_major }}/versions/${{ env.release_version }}.${{ env.date_stamp }})
215+
216+
Published to the Cloud: ✅

0 commit comments

Comments
 (0)