Skip to content

Commit f469086

Browse files
authored
Merge pull request #123 from basmeerman/feature/basmeerman-update-row
feat: add basmeerman distribution row to /update page
2 parents fe0ba1e + 77ea19f commit f469086

File tree

6 files changed

+398
-236
lines changed

6 files changed

+398
-236
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Nightly debug build — creates/updates a rolling "nightly" pre-release
2+
# with the latest debug firmware from master.
3+
#
4+
# The update page's "Latest Debug Build" button downloads from this release.
5+
# Pre-releases are skipped by /releases/latest, so Standard/Debug buttons
6+
# are unaffected.
7+
8+
name: Nightly Debug Build
9+
10+
on:
11+
push:
12+
branches:
13+
- master
14+
workflow_dispatch: # Allow manual trigger
15+
16+
permissions:
17+
contents: write # Needed to create/update releases
18+
19+
jobs:
20+
build-and-release:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
24+
25+
- name: Get short SHA
26+
id: sha
27+
run: echo "short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
28+
29+
- name: Get current datetime
30+
id: datetime
31+
run: echo "datetime=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
32+
33+
- name: Cache PlatformIO
34+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
35+
with:
36+
path: ~/.platformio
37+
key: '${{ runner.os }}-pio-${{ hashFiles(''SmartEVSE-3/platformio.ini'') }}'
38+
restore-keys: |
39+
${{ runner.os }}-pio-
40+
41+
- name: Set up Python
42+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
43+
with:
44+
python-version: '3.10'
45+
46+
- name: Install PlatformIO
47+
run: |
48+
python -m pip install --upgrade pip
49+
pip install --upgrade platformio
50+
51+
- name: Build standard firmware
52+
run: |
53+
PLATFORMIO_BUILD_FLAGS='-DVERSION=\"nightly-${{ steps.sha.outputs.short }}\" -DDBG=0' pio run -d SmartEVSE-3/
54+
mkdir -p ./dist
55+
56+
- name: Sign standard firmware
57+
env:
58+
super_secret: ${{ secrets.SECRET_RSA_KEY }}
59+
run: |
60+
if [ -z "$super_secret" ]; then
61+
echo "Signing key not available, shipping unsigned"
62+
cp ./SmartEVSE-3/.pio/build/release/firmware.bin ./dist/firmware.bin
63+
exit 0
64+
fi
65+
secret_file=$(mktemp)
66+
echo "$super_secret" > "$secret_file"
67+
openssl dgst -sign "$secret_file" -keyform PEM -sha256 -out firmware.sign -binary ./SmartEVSE-3/.pio/build/release/firmware.bin
68+
cat firmware.sign ./SmartEVSE-3/.pio/build/release/firmware.bin > ./dist/firmware.signed.bin
69+
rm -f "$secret_file"
70+
71+
- name: Build debug firmware
72+
run: |
73+
PLATFORMIO_BUILD_FLAGS='-DVERSION=\"nightly-${{ steps.sha.outputs.short }}\" -DDBG=1' pio run -d SmartEVSE-3/
74+
75+
- name: Sign debug firmware
76+
env:
77+
super_secret: ${{ secrets.SECRET_RSA_KEY }}
78+
run: |
79+
if [ -z "$super_secret" ]; then
80+
echo "Signing key not available, shipping unsigned"
81+
cp ./SmartEVSE-3/.pio/build/release/firmware.bin ./dist/firmware.debug.bin
82+
exit 0
83+
fi
84+
secret_file=$(mktemp)
85+
echo "$super_secret" > "$secret_file"
86+
openssl dgst -sign "$secret_file" -keyform PEM -sha256 -out firmware.sign -binary ./SmartEVSE-3/.pio/build/release/firmware.bin
87+
cat firmware.sign ./SmartEVSE-3/.pio/build/release/firmware.bin > ./dist/firmware.debug.signed.bin
88+
rm -f "$secret_file"
89+
90+
- name: Delete existing nightly release
91+
run: gh release delete nightly --yes --cleanup-tag 2>/dev/null || true
92+
env:
93+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
94+
95+
- name: Create nightly pre-release
96+
uses: softprops/action-gh-release@26994186c0ac3ef5cae75ac16aa32e8153525f77 # v1
97+
with:
98+
tag_name: nightly
99+
name: "Nightly Debug Build (${{ steps.sha.outputs.short }})"
100+
body: |
101+
Automated nightly build from master at ${{ steps.datetime.outputs.datetime }}.
102+
Commit: ${{ github.sha }}
103+
104+
Use the "Latest Debug Build" button on the /update page to flash this build.
105+
draft: false
106+
prerelease: true
107+
token: ${{ secrets.GITHUB_TOKEN }}
108+
files: |
109+
dist/*

.github/workflows/pio-release.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ jobs:
7777
token: ${{ secrets.GITHUB_TOKEN }}
7878
files: |
7979
${{ steps.tag.outputs.tag }}-dist.zip
80+
dist/firmware.signed.bin
81+
dist/firmware.debug.signed.bin
8082
SmartEVSE-3/test/native/traceability-report.html
8183
8284
- name: Configure AWS Credentials

SmartEVSE-3/data/update2.html

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
let REPO_FACT="SmartEVSE-3";
1616
let OWNER_COMM="dingo35";
1717
let REPO_COMM="SmartEVSE-3.5";
18+
let OWNER_BASM="basmeerman";
19+
let REPO_BASM="SmartEVSE-3.5";
1820
let update_url="";
1921
// Helper function to display upload status
2022
var setStatus = function(text) {
@@ -41,8 +43,10 @@
4143
console.error('Error: ', err)
4244
})
4345
}
44-
function update_fw(owner, debug) {
45-
fetch("/autoupdate?owner=" + owner + "&debug=" + debug)
46+
function update_fw(owner, debug, tag) {
47+
var url = "/autoupdate?owner=" + owner + "&debug=" + debug;
48+
if (tag) url += "&tag=" + tag;
49+
fetch(url)
4650
.then(res => res.json())
4751
.then(data => {
4852
setStatus('Firmware update progress: ' + data.progress + '/' + data.size);
@@ -90,6 +94,16 @@
9094
<td><button onclick="update_fw(OWNER_COMM, 0)" style="width: 100px; display:inline-block;">Standard</button>
9195
<td><button onclick="update_fw(OWNER_COMM, 1)" style="width: 100px; display:inline-block;">Debug</button>
9296
</tr>
97+
<tr>
98+
<td>Community</td>
99+
<td>bleediest edge</td>
100+
<td><a href="https://github.com/"
101+
onclick="location.href=this.href + OWNER_BASM + '/' + REPO_BASM + '/releases';return false;"><script>document.write(OWNER_BASM)</script></a></td>
102+
<td><div id="latest_basm"></div></td>
103+
<td><button onclick="update_fw(OWNER_BASM, 0)" style="width: 100px; display:inline-block;">Standard</button>
104+
<td><button onclick="update_fw(OWNER_BASM, 1)" style="width: 100px; display:inline-block;">Debug</button>
105+
<td><button onclick="update_fw(OWNER_BASM, 1, 'nightly')" style="width: 140px; display:inline-block;">Latest Debug Build</button>
106+
</tr>
93107
</table>
94108
<br>
95109
=======================================================
@@ -121,6 +135,7 @@
121135
document.getElementById("version").innerHTML = sessionStorage.getItem("version");
122136
getLatestVersion(OWNER_FACT, REPO_FACT, 'latest_fact');
123137
getLatestVersion(OWNER_COMM, REPO_COMM, 'latest_comm');
138+
getLatestVersion(OWNER_BASM, REPO_BASM, 'latest_basm');
124139
}
125140

126141
async function getLatestVersion(owner, repo, element) {

SmartEVSE-3/src/network_common.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,18 +1523,40 @@ static void fn_http_server(struct mg_connection *c, int ev, void *ev_data) {
15231523
} else if (mg_http_match_uri(hm, "/autoupdate")) {
15241524
char owner[40];
15251525
char buf[8];
1526+
char tag[40] = "";
15261527
int debug;
15271528
mg_http_get_var(&hm->query, "owner", owner, sizeof(owner));
15281529
mg_http_get_var(&hm->query, "debug", buf, sizeof(buf));
1530+
mg_http_get_var(&hm->query, "tag", tag, sizeof(tag));
15291531
debug = strtol(buf, NULL, 0);
15301532
if (!memcmp(owner, OWNER_FACT, sizeof(OWNER_FACT)) || (!memcmp(owner, OWNER_COMM, sizeof(OWNER_COMM)))) {
1533+
// Factory/Community: use S3 direct download (existing behavior)
15311534
if (downloadUrl) { free(downloadUrl); downloadUrl = NULL; }
15321535
#ifdef SENSORBOX_VERSION
15331536
asprintf(&downloadUrl, "%s/%s_sensorboxv2_firmware.%ssigned.bin", FW_DOWNLOAD_PATH, owner, debug ? "debug.": ""); //will be freed in FirmwareUpdate() ; format: http://s3.com/dingo35_sensorboxv2_firmware.debug.signed.bin
15341537
#else
15351538
asprintf(&downloadUrl, "%s/%s_firmware.%ssigned.bin", FW_DOWNLOAD_PATH, owner, debug ? "debug.": ""); //will be freed in FirmwareUpdate() ; format: http://s3.com/dingo35_firmware.debug.signed.bin
15361539
#endif
15371540
RunFirmwareUpdate();
1541+
} else if (!memcmp(owner, OWNER_BASM, sizeof(OWNER_BASM))) {
1542+
// basmeerman fork: download from GitHub release assets
1543+
// tag parameter selects which release (e.g. "nightly" for pre-release, or latest tag)
1544+
if (downloadUrl) { free(downloadUrl); downloadUrl = NULL; }
1545+
if (tag[0]) {
1546+
// Specific tag requested (e.g. nightly pre-release)
1547+
asprintf(&downloadUrl, "%s/%s/%s/releases/download/%s/firmware.%ssigned.bin",
1548+
GH_RELEASE_URL, OWNER_BASM, REPO_BASM, tag, debug ? "debug." : "");
1549+
} else {
1550+
// Use getLatestVersion to find the latest release tag, then build URL
1551+
char version[32] = "";
1552+
String owner_repo = String(OWNER_BASM) + "/" + REPO_BASM;
1553+
String asset_name = String("firmware.") + (debug ? "debug." : "") + "signed.bin";
1554+
if (getLatestVersion(owner_repo, asset_name, version) && version[0]) {
1555+
asprintf(&downloadUrl, "%s/%s/%s/releases/download/%s/firmware.%ssigned.bin",
1556+
GH_RELEASE_URL, OWNER_BASM, REPO_BASM, version, debug ? "debug." : "");
1557+
}
1558+
}
1559+
if (downloadUrl) RunFirmwareUpdate();
15381560
} // after the first call we just report progress
15391561
DynamicJsonDocument doc(64); // https://arduinojson.org/v6/assistant/
15401562
doc["progress"] = downloadProgress;

SmartEVSE-3/src/network_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,8 @@ extern String homeWizardManualIP;
172172
#define REPO_FACT "SmartEVSE-3"
173173
#define OWNER_COMM "dingo35"
174174
#define REPO_COMM "SmartEVSE-3.5"
175+
#define OWNER_BASM "basmeerman"
176+
#define REPO_BASM "SmartEVSE-3.5"
177+
#define GH_RELEASE_URL "https://github.com"
175178

176179
#endif

0 commit comments

Comments
 (0)