1
- name : Check, Release, Build and Publish WSL2 Image
1
+ name : Check, Build & Publish WSL2 Image
2
2
3
3
on :
4
+ # Nightly check at 00:00 UTC
4
5
schedule :
5
- # Run daily at midnight UTC
6
6
- cron : ' 0 0 * * *'
7
+ # Manual “Run workflow” button
7
8
workflow_dispatch :
8
- # Allow manual triggering
9
+ # When you click “Publish release” in the UI
9
10
release :
10
11
types : [published]
11
12
12
13
permissions :
13
- contents : write
14
+ contents : write # required for tag push & gh‑release
14
15
15
16
jobs :
17
+ # ------------------------------------------------------------
18
+ # 1. Decide whether we need a new release tag
19
+ # (runs on schedule or workflow‑dispatch, never on release)
20
+ # ------------------------------------------------------------
16
21
check-and-release :
17
- runs-on : ubuntu-latest
18
- # Skip this job if triggered by a release event
19
22
if : github.event_name != 'release'
23
+ runs-on : ubuntu-latest
20
24
outputs :
21
- NEED_RELEASE : ${{ steps.release .outputs.NEED_RELEASE }}
22
- NEW_TAG : ${{ steps.release .outputs.NEW_TAG }}
25
+ NEED_RELEASE : ${{ steps.decide .outputs.NEED_RELEASE }}
26
+ NEW_TAG : ${{ steps.decide .outputs.NEW_TAG }}
23
27
steps :
24
- - name : Checkout Repository
28
+ - name : Checkout repository ⚡
25
29
uses : actions/checkout@v4
26
30
with :
27
- fetch-depth : 0 # Fetch all history to get tags
31
+ fetch-depth : 0 # get full history
32
+ fetch-tags : true # still unreliable; we force‑fetch below
33
+
34
+ - name : Ensure ALL tags are present
35
+ run : git fetch --tags --prune --force
28
36
29
- - name : Get latest containerlab version
30
- id : containerlab
37
+ - name : Get latest Containerlab version
38
+ id : clab
39
+ shell : bash
31
40
run : |
32
- # Get latest version by following the redirect to the latest release
33
- LATEST_URL=$(curl -sLI -o /dev/null -w '%{url_effective}' https://github.com/srl-labs/containerlab/releases/latest)
34
- echo "Latest release URL: $LATEST_URL"
35
-
36
- # Extract version from URL
37
- CONTAINERLAB_LATEST=$(echo $LATEST_URL | rev | cut -d'/' -f1 | rev)
38
-
39
- # Remove the 'v' prefix
40
- CONTAINERLAB_VERSION=${CONTAINERLAB_LATEST#v}
41
- echo "CONTAINERLAB_VERSION=$CONTAINERLAB_VERSION" >> $GITHUB_OUTPUT
42
- echo "Latest containerlab version: $CONTAINERLAB_VERSION"
43
-
44
- - name : Get latest WSL release version
45
- id : current_release
41
+ set -euo pipefail
42
+ latest_url=$(curl -sLI -o /dev/null -w '%{url_effective}' \
43
+ https://github.com/srl-labs/containerlab/releases/latest)
44
+ ver=${latest_url##*/}
45
+ echo "CONTAINERLAB_VER=${ver#v}" >> "$GITHUB_OUTPUT"
46
+ echo "Found Containerlab ${ver#v}"
47
+
48
+ - name : Get latest WSL image tag
49
+ id : current
50
+ shell : bash
46
51
run : |
47
- # Get the latest release tag from this repository
48
- LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")
49
- echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_OUTPUT
50
-
51
- if [[ "$LATEST_TAG" == "none" ]]; then
52
- echo "No releases found"
53
- echo "CURRENT_CONTAINERLAB_VERSION=none" >> $GITHUB_OUTPUT
54
- echo "CURRENT_WSL_VERSION=none" >> $GITHUB_OUTPUT
55
- else
56
- # Parse the version (format: 0.65.1-1.0)
57
- CURRENT_CONTAINERLAB_VERSION=$(echo $LATEST_TAG | cut -d'-' -f1)
58
- CURRENT_WSL_VERSION=$(echo $LATEST_TAG | cut -d'-' -f2)
59
- echo "CURRENT_CONTAINERLAB_VERSION=$CURRENT_CONTAINERLAB_VERSION" >> $GITHUB_OUTPUT
60
- echo "CURRENT_WSL_VERSION=$CURRENT_WSL_VERSION" >> $GITHUB_OUTPUT
61
- echo "Current containerlab version: $CURRENT_CONTAINERLAB_VERSION"
62
- echo "Current WSL version: $CURRENT_WSL_VERSION"
52
+ set -euo pipefail
53
+ tag=$(git tag --list --sort=-v:refname | head -n1 || true)
54
+ echo "LATEST_TAG=$tag" >> "$GITHUB_OUTPUT"
55
+
56
+ if [[ -z "$tag" ]]; then
57
+ echo "CONTAINERLAB_CUR=none" >> "$GITHUB_OUTPUT"
58
+ echo "WSL_CUR=none" >> "$GITHUB_OUTPUT"
59
+ exit 0
63
60
fi
64
61
65
- - name : Determine if release is needed
66
- id : release
62
+ echo "Latest tag is $tag"
63
+
64
+ echo "CONTAINERLAB_CUR=${tag%%-*}" >> "$GITHUB_OUTPUT"
65
+ echo "WSL_CUR=${tag#*-}" >> "$GITHUB_OUTPUT"
66
+
67
+ - name : Decide whether to cut a new tag
68
+ id : decide
69
+ shell : bash
67
70
run : |
68
- NEED_RELEASE="false"
69
- NEW_WSL_VERSION="1.0"
71
+ set -euo pipefail
70
72
71
- # Always build when manually triggered via workflow_dispatch
72
- if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
73
- NEED_RELEASE="true"
74
- echo "Manual trigger detected - forcing release"
75
- # Check if containerlab version is different
76
- elif [[ "${{ steps.current_release.outputs.CURRENT_CONTAINERLAB_VERSION }}" != "${{ steps.containerlab.outputs.CONTAINERLAB_VERSION }}" ]]; then
77
- NEED_RELEASE="true"
78
- elif [[ "${{ steps.current_release.outputs.CURRENT_CONTAINERLAB_VERSION }}" == "none" ]]; then
79
- # No previous releases
80
- NEED_RELEASE="true"
81
- fi
73
+ need_release="false"
74
+ new_clab="${{ steps.clab.outputs.CONTAINERLAB_VER }}"
75
+ cur_clab="${{ steps.current.outputs.CONTAINERLAB_CUR }}"
76
+ cur_wsl="${{ steps.current.outputs.WSL_CUR }}"
77
+ new_wsl="1.0"
82
78
83
- # For manual triggers with no version change, use current containerlab version with bumped WSL version
84
- if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ steps.current_release.outputs.CURRENT_CONTAINERLAB_VERSION }}" == "${{ steps.containerlab.outputs.CONTAINERLAB_VERSION }}" ]]; then
85
- # Increment the WSL version
86
- if [[ "${{ steps.current_release.outputs.CURRENT_WSL_VERSION }}" != "none" ]]; then
87
- CURRENT_WSL_VERSION="${{ steps.current_release.outputs.CURRENT_WSL_VERSION }}"
88
- # Extract major and minor version parts
89
- WSL_MAJOR=$(echo $CURRENT_WSL_VERSION | cut -d'.' -f1)
90
- WSL_MINOR=$(echo $CURRENT_WSL_VERSION | cut -d'.' -f2)
91
- # Increment minor version
92
- NEW_WSL_MINOR=$((WSL_MINOR + 1))
93
- NEW_WSL_VERSION="$WSL_MAJOR.$NEW_WSL_MINOR "
94
- fi
95
- echo "Using existing containerlab version with incremented WSL version: $NEW_WSL_VERSION "
79
+ bump_wsl () {
80
+ local major=${cur_wsl%%.*}
81
+ local minor=${cur_wsl#*.}
82
+ new_wsl= "${major}.$((minor+1))"
83
+ }
84
+
85
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
86
+ need_release="true"
87
+ [[ "$cur_clab" == "$new_clab" && "$cur_wsl" != "none" ]] && bump_wsl
88
+ elif [[ "$cur_clab" == "none" ]]; then
89
+ need_release="true "
90
+ elif [[ "$cur_clab" != "$new_clab" ]]; then
91
+ need_release="true "
96
92
fi
97
93
98
- # Set output variables
99
- echo "NEED_RELEASE=$NEED_RELEASE" >> $GITHUB_OUTPUT
100
- echo "NEW_TAG=${{ steps.containerlab.outputs.CONTAINERLAB_VERSION }}-$NEW_WSL_VERSION" >> $GITHUB_OUTPUT
94
+ echo "NEED_RELEASE=$need_release" >> "$GITHUB_OUTPUT"
101
95
102
- if [[ "$NEED_RELEASE" == "true" ]]; then
103
- echo "Release needed: ${{ steps.containerlab.outputs.CONTAINERLAB_VERSION }}-$NEW_WSL_VERSION"
96
+ if [[ "$need_release" == "true" ]]; then
97
+ new_tag="${new_clab}-${new_wsl}"
98
+ echo "NEW_TAG=$new_tag" >> "$GITHUB_OUTPUT"
99
+ echo "Releasing $new_tag"
104
100
else
105
- echo "No release needed. Latest containerlab version already supported. "
101
+ echo "No release required "
106
102
fi
107
103
108
- - name : Create Release Tag
109
- if : steps.release .outputs.NEED_RELEASE == 'true'
104
+ - name : Create Git tag
105
+ if : steps.decide .outputs.NEED_RELEASE == 'true'
110
106
run : |
111
107
git config --local user.email "[email protected] "
112
- git config --local user.name "GitHub Actions"
113
- git tag -a ${{ steps.release.outputs.NEW_TAG }} -m "Release ${{ steps.release.outputs.NEW_TAG }}"
114
- git push origin ${{ steps.release.outputs.NEW_TAG }}
108
+ git config --local user.name "GitHub Actions"
109
+ git tag -a "${{ steps.decide.outputs.NEW_TAG }}" \
110
+ -m "Release ${{ steps.decide.outputs.NEW_TAG }}"
111
+ git push origin "${{ steps.decide.outputs.NEW_TAG }}"
115
112
116
- - name : Create GitHub Release
117
- if : steps.release .outputs.NEED_RELEASE == 'true'
113
+ - name : Draft GitHub Release
114
+ if : steps.decide .outputs.NEED_RELEASE == 'true'
118
115
uses : softprops/action-gh-release@v1
119
116
with :
120
- tag_name : ${{ steps.release .outputs.NEW_TAG }}
121
- name : " Release ${{ steps.release .outputs.NEW_TAG }}"
117
+ tag_name : ${{ steps.decide .outputs.NEW_TAG }}
118
+ name : " Release ${{ steps.decide .outputs.NEW_TAG }}"
122
119
body : |
123
- WSL2 image for containerlab version ${{ steps.containerlab .outputs.CONTAINERLAB_VERSION }}
124
-
125
- ${{ github.event_name == 'workflow_dispatch' && 'This release was manually triggered.' || 'This release was automatically generated based on the latest containerlab release.' }}
120
+ WSL2 image for Containerlab ${{ steps.clab .outputs.CONTAINERLAB_VER }}
121
+
122
+ ${{ github.event_name == 'workflow_dispatch' && 'Manually triggered.' || 'Automated nightly release.' }}
126
123
draft : false
127
124
prerelease : false
128
125
129
- # This job runs when triggered by a release event (manual release)
130
- build-and-publish-from-release :
131
- runs-on : ubuntu-22.04
132
- if : github.event_name == 'release'
133
- steps :
134
- - name : Checkout Repository
135
- uses : actions/checkout@v4
136
-
137
- - name : Set up Docker Buildx
138
- uses : docker/setup-buildx-action@v2
139
-
140
- - name : Build Docker Image
141
- run : |
142
- docker build . --tag clab-wsl-debian
143
-
144
- - name : Run Docker Container and Export Filesystem
145
- run : |
146
- # Run the Docker container
147
- docker run -t --name wsl_export clab-wsl-debian ls /
148
- # Export the container's filesystem to a tar file
149
- docker export wsl_export -o clab.tar
150
- # Remove the container to clean up
151
- docker rm wsl_export
152
-
153
- - name : Rename tar to .wsl file
154
- run : |
155
- # Rename the tar file to have a .wsl extension
156
- mv clab.tar clab.wsl
157
-
158
- - name : Upload WSL Image Artifact
159
- uses : actions/upload-artifact@v4
160
- with :
161
- name : clab-wsl2
162
- path : clab.wsl
163
-
164
- - name : Get release tag
165
- id : get_tag
166
- run : |
167
- # For releases triggered by the release event
168
- REF_NAME="${{ github.ref }}"
169
- TAG="${REF_NAME#refs/tags/}"
170
- echo "Using release tag: $TAG"
171
- echo "TAG=$TAG" >> $GITHUB_OUTPUT
172
-
173
- - name : Upload Release Asset
174
- uses : svenstaro/upload-release-action@v2
175
- with :
176
- repo_token : ${{ secrets.GITHUB_TOKEN }}
177
- file : clab.wsl
178
- asset_name : clab-${{ steps.get_tag.outputs.TAG }}.wsl
179
- tag : ${{ steps.get_tag.outputs.TAG }}
180
-
181
- # This job runs when triggered by a schedule or workflow_dispatch event and a release is needed
182
- build-and-publish-from-check :
126
+ # ------------------------------------------------------------
127
+ # 2. Build & upload WSL image when we *have* a tag
128
+ # ------------------------------------------------------------
129
+ build-and-publish :
130
+ needs : check-and-release
131
+ if : needs.check-and-release.outputs.NEED_RELEASE == 'true' || github.event_name == 'release'
183
132
runs-on : ubuntu-22.04
184
- needs : [check-and-release]
185
- if : needs.check-and-release.outputs.NEED_RELEASE == 'true'
186
133
steps :
187
- - name : Checkout Repository
188
- uses : actions/checkout@v4
134
+ - uses : actions/checkout@v4
189
135
190
- - name : Set up Docker Buildx
191
- uses : docker/setup-buildx-action@v2
136
+ - uses : docker/setup-buildx-action@v2
192
137
193
- - name : Build Docker Image
194
- run : |
195
- docker build . --tag clab-wsl-debian
138
+ - name : Build Docker image
139
+ run : docker build . -t clab-wsl-debian
196
140
197
- - name : Run Docker Container and Export Filesystem
141
+ - name : Export container filesystem ➜ .wsl
198
142
run : |
199
- # Run the Docker container
200
143
docker run -t --name wsl_export clab-wsl-debian ls /
201
- # Export the container's filesystem to a tar file
202
- docker export wsl_export -o clab.tar
203
- # Remove the container to clean up
204
- docker rm wsl_export
205
-
206
- - name : Rename tar to .wsl file
207
- run : |
208
- # Rename the tar file to have a .wsl extension
209
- mv clab.tar clab.wsl
144
+ docker export wsl_export -o clab.tar
145
+ docker rm wsl_export
146
+ mv clab.tar clab.wsl
210
147
211
- - name : Upload WSL Image Artifact
212
- uses : actions/upload-artifact@v4
148
+ - uses : actions/upload-artifact@v4
213
149
with :
214
150
name : clab-wsl2
215
151
path : clab.wsl
216
152
217
- - name : Get release tag
218
- id : get_tag
153
+ - name : Determine tag name
154
+ id : tag
219
155
run : |
220
- # For releases created by the check-and-release job
221
- echo "Using new tag: ${{ needs.check-and-release.outputs.NEW_TAG }}"
222
- echo "TAG=${{ needs.check-and-release.outputs.NEW_TAG }}" >> $GITHUB_OUTPUT
156
+ if [[ "${{ github.event_name }}" == "release" ]]; then
157
+ echo "TAG=${GITHUB_REF##*/}" >> "$GITHUB_OUTPUT"
158
+ else
159
+ echo "TAG=${{ needs.check-and-release.outputs.NEW_TAG }}" >> "$GITHUB_OUTPUT"
160
+ fi
223
161
224
- - name : Upload Release Asset
162
+ - name : Upload release asset
225
163
uses : svenstaro/upload-release-action@v2
226
164
with :
227
165
repo_token : ${{ secrets.GITHUB_TOKEN }}
228
166
file : clab.wsl
229
- asset_name : clab-${{ steps.get_tag .outputs.TAG }}.wsl
230
- tag : ${{ steps.get_tag .outputs.TAG }}
167
+ asset_name : clab-${{ steps.tag .outputs.TAG }}.wsl
168
+ tag : ${{ steps.tag .outputs.TAG }}
0 commit comments