Skip to content

Commit 0f82730

Browse files
authored
Release engineering improvements (wled#1844)
* version set from package.json and release bin names * support direnv virtualenv * versioned PlatformIO environment * matrix support for parralel CI * gather artifacts * release on tagging * minor scripts formatting
1 parent ff083da commit 0f82730

11 files changed

+216
-76
lines changed

.envrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
layout python-venv python3

.github/workflows/wled-ci.yml

+61-6
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,37 @@ name: PlatformIO CI
33
on: [push, pull_request]
44

55
jobs:
6-
build:
76

7+
get_default_envs:
8+
name: Gather Environments
89
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v2
12+
- name: Cache pip
13+
uses: actions/cache@v2
14+
with:
15+
path: ~/.cache/pip
16+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
17+
restore-keys: |
18+
${{ runner.os }}-pip-
19+
- uses: actions/setup-python@v2
20+
- name: Install PlatformIO
21+
run: pip install -r requirements.txt
22+
- name: Get default environments
23+
id: envs
24+
run: |
25+
echo "::set-output name=environments::$(pio project config --json-output | jq -cr '.[0][1][0][1]')"
26+
outputs:
27+
environments: ${{ steps.envs.outputs.environments }}
28+
929

30+
build:
31+
name: Build Enviornments
32+
runs-on: ubuntu-latest
33+
needs: get_default_envs
34+
strategy:
35+
matrix:
36+
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
1037
steps:
1138
- uses: actions/checkout@v2
1239
- name: Cache pip
@@ -24,8 +51,36 @@ jobs:
2451
- name: Set up Python
2552
uses: actions/setup-python@v2
2653
- name: Install PlatformIO
27-
run: |
28-
python -m pip install --upgrade pip
29-
pip install --upgrade platformio
30-
- name: Run PlatformIO
31-
run: pio run
54+
run: pip install -r requirements.txt
55+
- name: Build firmware
56+
env:
57+
WLED_RELEASE: True
58+
run: pio run -e ${{ matrix.environment }}
59+
- uses: actions/upload-artifact@v2
60+
with:
61+
name: firmware-${{ matrix.environment }}
62+
path: |
63+
build_output/firmware/*.bin
64+
build_output/firmware/*.gz
65+
- uses: actions/upload-artifact@v2
66+
if: startsWith(github.ref, 'refs/tags/')
67+
with:
68+
name: firmware-release
69+
path: build_output/release/*.bin
70+
release:
71+
name: Create Release
72+
runs-on: ubuntu-latest
73+
needs: [get_default_envs, build]
74+
if: startsWith(github.ref, 'refs/tags/')
75+
steps:
76+
- uses: actions/download-artifact@v2
77+
with:
78+
name: firmware-release
79+
- name: Create draft release
80+
uses: softprops/action-gh-release@v1
81+
with:
82+
draft: True
83+
files: |
84+
*.bin
85+
env:
86+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
.clang-format
1515
node_modules
1616
.idea
17+
.direnv

pio-scripts/gzip-firmware.py

-23
This file was deleted.

pio-scripts/name-firmware.py

-34
This file was deleted.

pio-scripts/output_bins.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
Import('env')
2+
import os
3+
import shutil
4+
import gzip
5+
6+
OUTPUT_DIR = "build_output{}".format(os.path.sep)
7+
8+
def _get_cpp_define_value(env, define):
9+
define_list = [item[-1] for item in env["CPPDEFINES"] if item[0] == define]
10+
11+
if define_list:
12+
return define_list[0]
13+
14+
return None
15+
16+
def _create_dirs(dirs=["firmware", "map"]):
17+
# check if output directories exist and create if necessary
18+
if not os.path.isdir(OUTPUT_DIR):
19+
os.mkdir(OUTPUT_DIR)
20+
21+
for d in dirs:
22+
if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)):
23+
os.mkdir("{}{}".format(OUTPUT_DIR, d))
24+
25+
def bin_rename_copy(source, target, env):
26+
_create_dirs()
27+
variant = env["PIOENV"]
28+
29+
# create string with location and file names based on variant
30+
map_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant)
31+
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
32+
33+
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
34+
35+
if release_name and os.getenv("WLED_RELEASE"):
36+
_create_dirs(["release"])
37+
version = _get_cpp_define_value(env, "WLED_VERSION")
38+
release_file = "{}release{}WLED_{}_{}.bin".format(OUTPUT_DIR, os.path.sep, version, release_name)
39+
shutil.copy(str(target[0]), release_file)
40+
41+
# check if new target files exist and remove if necessary
42+
for f in [map_file, bin_file]:
43+
if os.path.isfile(f):
44+
os.remove(f)
45+
46+
# copy firmware.bin to firmware/<variant>.bin
47+
shutil.copy(str(target[0]), bin_file)
48+
49+
# copy firmware.map to map/<variant>.map
50+
if os.path.isfile("firmware.map"):
51+
shutil.move("firmware.map", map_file)
52+
53+
def bin_gzip(source, target, env):
54+
_create_dirs()
55+
variant = env["PIOENV"]
56+
57+
# create string with location and file names based on variant
58+
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
59+
gzip_file = "{}firmware{}{}.bin.gz".format(OUTPUT_DIR, os.path.sep, variant)
60+
61+
# check if new target files exist and remove if necessary
62+
if os.path.isfile(gzip_file): os.remove(gzip_file)
63+
64+
# write gzip firmware file
65+
with open(bin_file,"rb") as fp:
66+
with gzip.open(gzip_file, "wb", compresslevel = 9) as f:
67+
shutil.copyfileobj(fp, f)
68+
69+
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_rename_copy, bin_gzip])

pio-scripts/set_version.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Import('env')
2+
import json
3+
4+
PACKAGE_FILE = "package.json"
5+
6+
with open(PACKAGE_FILE, "r") as package:
7+
version = json.load(package)["version"]
8+
env.Append(BUILD_FLAGS=[f"-DWLED_VERSION={version}"])

platformio.ini

+9-8
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,11 @@ build_flags = -g
151151
-DCONFIG_LITTLEFS_FOR_IDF_3_2
152152

153153
[scripts_defaults]
154-
extra_scripts = pio-scripts/name-firmware.py
155-
pio-scripts/gzip-firmware.py
156-
pio-scripts/strip-floats.py
157-
pio-scripts/user_config_copy.py
154+
extra_scripts =
155+
pre:pio-scripts/set_version.py
156+
post:pio-scripts/output_bins.py
157+
post:pio-scripts/strip-floats.py
158+
pre:pio-scripts/user_config_copy.py
158159

159160
# ------------------------------------------------------------------------------
160161
# COMMON SETTINGS:
@@ -213,15 +214,15 @@ platform = ${common.platform_wled_default}
213214
platform_packages = ${common.platform_packages}
214215
board_build.ldscript = ${common.ldscript_4m1m}
215216
build_unflags = ${common.build_unflags}
216-
build_flags = ${common.build_flags_esp8266}
217+
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266
217218

218219
[env:esp01_1m_full]
219220
board = esp01_1m
220221
platform = ${common.platform_wled_default}
221222
platform_packages = ${common.platform_packages}
222223
board_build.ldscript = ${common.ldscript_1m128k}
223224
build_unflags = ${common.build_unflags}
224-
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA
225+
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA
225226

226227
[env:esp07]
227228
board = esp07
@@ -261,7 +262,7 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
261262
board = esp32dev
262263
263264
build_unflags = ${common.build_unflags}
264-
build_flags = ${common.build_flags_esp32}
265+
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32
265266
lib_ignore =
266267
ESPAsyncTCP
267268
ESPAsyncUDP
@@ -271,7 +272,7 @@ board = esp32-poe
271272
272273
upload_speed = 921600
273274
build_unflags = ${common.build_unflags}
274-
build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
275+
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
275276
lib_ignore =
276277
ESPAsyncTCP
277278
ESPAsyncUDP

requirements.in

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
platformio

requirements.txt

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#
2+
# This file is autogenerated by pip-compile
3+
# To update, run:
4+
#
5+
# pip-compile
6+
#
7+
aiofiles==0.6.0
8+
# via platformio
9+
ajsonrpc==1.1.0
10+
# via platformio
11+
bottle==0.12.19
12+
# via platformio
13+
certifi==2020.12.5
14+
# via requests
15+
chardet==4.0.0
16+
# via requests
17+
click==7.1.2
18+
# via
19+
# platformio
20+
# uvicorn
21+
colorama==0.4.4
22+
# via platformio
23+
h11==0.12.0
24+
# via
25+
# uvicorn
26+
# wsproto
27+
idna==2.10
28+
# via requests
29+
ifaddr==0.1.7
30+
# via zeroconf
31+
marshmallow==3.11.1
32+
# via platformio
33+
platformio==5.1.1
34+
# via -r requirements.in
35+
pyelftools==0.27
36+
# via platformio
37+
pyserial==3.5
38+
# via platformio
39+
requests==2.25.1
40+
# via platformio
41+
semantic-version==2.8.5
42+
# via platformio
43+
starlette==0.14.2
44+
# via platformio
45+
tabulate==0.8.9
46+
# via platformio
47+
urllib3==1.26.4
48+
# via requests
49+
uvicorn==0.13.4
50+
# via platformio
51+
wsproto==1.0.0
52+
# via platformio
53+
zeroconf==0.28.8
54+
# via platformio

wled00/wled.h

+12-5
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
//This is generally a terrible idea, but improves boot success on boards with a 3.3v regulator + cap setup that can't provide 400mA peaks
5252
//#define WLED_DISABLE_BROWNOUT_DET
5353

54-
// Library inclusions.
54+
// Library inclusions.
5555
#include <Arduino.h>
5656
#ifdef ESP8266
5757
#include <ESP8266WiFi.h>
@@ -171,8 +171,15 @@
171171
# define _INIT_N(x) UNPACK x
172172
#endif
173173

174+
#define STRINGIFY(X) #X
175+
#define TOSTRING(X) STRINGIFY(X)
176+
177+
#ifndef WLED_VERSION
178+
#define WLED_VERSION "dev"
179+
#endif
180+
174181
// Global Variable definitions
175-
WLED_GLOBAL char versionString[] _INIT("0.12.0");
182+
WLED_GLOBAL char versionString[] _INIT(TOSTRING(WLED_VERSION));
176183
#define WLED_CODENAME "Hikari"
177184

178185
// AP and OTA default passwords (for maximum security change them!)
@@ -203,7 +210,7 @@ WLED_GLOBAL int8_t irPin _INIT(4);
203210
WLED_GLOBAL int8_t irPin _INIT(IRPIN);
204211
#endif
205212

206-
//WLED_GLOBAL byte presetToApply _INIT(0);
213+
//WLED_GLOBAL byte presetToApply _INIT(0);
207214

208215
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
209216

@@ -224,7 +231,7 @@ WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling
224231
WLED_GLOBAL int ethernetType _INIT(WLED_ETH_DEFAULT); // ethernet board type
225232
#else
226233
WLED_GLOBAL int ethernetType _INIT(WLED_ETH_NONE); // use none for ethernet board type if default not defined
227-
#endif
234+
#endif
228235
#endif
229236

230237
// LED CONFIG
@@ -548,7 +555,7 @@ WLED_GLOBAL bool e131NewData _INIT(false);
548555
// led fx library object
549556
WLED_GLOBAL BusManager busses _INIT(BusManager());
550557
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
551-
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES] _INIT({nullptr}); //temporary, to remember values from network callback until after
558+
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES] _INIT({nullptr}); //temporary, to remember values from network callback until after
552559
WLED_GLOBAL bool doInitBusses _INIT(false);
553560

554561
// Usermod manager

0 commit comments

Comments
 (0)