Skip to content

Commit fbb7e0d

Browse files
malysclaude
andcommitted
feat: MIT licence, new repo URL, comparable nightly versions
Licence: MIT, per the project owner's decision. The copyright line names both Leon Kernan, whose original ABRP_Uploader a meaningful part of this code still is, and this fork's contributors -- MIT requires that notice to travel with any copy. LICENSE.md records that the upstream repo carried no licence of its own and that applying MIT here was the owner's call. Remote and in-app URLs move to malys/MG4AbrpTelemetry. Fixes a defect in the nightly channel I introduced with it: the workflow tagged pre-releases "nightly-<run>", and the updater parses numeric segments, so that tag resolved to version 0 and could never look newer than an installed build. The channel would have shipped and silently never updated anyone. Nightly builds now carry the build number inside the numeric core of the version ("1.0.42-nightly") rather than in the suffix, the CI tags them "v1.0.42", and a printNightlyVersion task keeps the tag and the APK in step instead of hardcoding a base version in the workflow. Tests cover the comparison, including an assertion that the old "nightly-43" form parses to 0 -- so nobody reintroduces it. The updater also now picks the highest pre-release version rather than the first one the API happens to return: that ordering is by creation date, so a re-published release could otherwise beat a newer one. Stable releases stay excluded -- they could not update a nightly install anyway, since the nightly applicationId carries a .nightly suffix. 55 tests green on nightly, 45 on stable; lint and permission gate pass; nightly release APK builds as MG4AbrpTelemetry-nightly-1.0.42-nightly.apk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ef6abeb commit fbb7e0d

7 files changed

Lines changed: 78 additions & 56 deletions

File tree

‎.github/ISSUE_TEMPLATE/config.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Security vulnerability
4-
url: https://github.com/malys/ABRP_Uploader/security/advisories/new
4+
url: https://github.com/malys/MG4AbrpTelemetry/security/advisories/new
55
about: Report privately, never in a public issue.
66
- name: ABRP telemetry API questions
77
url: https://documenter.getpostman.com/view/7396339/SWTK5a8w

‎.github/workflows/nightly.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
ABRP_KEYSTORE_PASSWORD: ${{ secrets.ABRP_KEYSTORE_PASSWORD }}
6767
ABRP_KEY_ALIAS: ${{ secrets.ABRP_KEY_ALIAS }}
6868
ABRP_KEY_PASSWORD: ${{ secrets.ABRP_KEY_PASSWORD }}
69-
run: ./gradlew assembleNightlyRelease --no-daemon
69+
run: ./gradlew assembleNightlyRelease -PnightlyBuild=${{ github.run_number }} --no-daemon
7070

7171
- name: Collect APK
7272
if: steps.guard.outputs.skip != 'true'
@@ -81,8 +81,8 @@ jobs:
8181
with:
8282
# The in-app updater compares this tag against the installed version, so it
8383
# must stay parseable as a version.
84-
tag_name: nightly-${{ github.run_number }}
85-
name: Nightly ${{ github.run_number }}
84+
tag_name: v${{ steps.version.outputs.value }}
85+
name: Nightly ${{ steps.version.outputs.value }}
8686
prerelease: true
8787
files: dist/*.apk
8888
body: |

‎LICENSE‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Leon Kernan (original ABRP_Uploader)
4+
Copyright (c) 2026 MG4 ABRP Telemetry contributors
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

‎LICENSE.md‎

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,19 @@
1-
# Licensing status
1+
# Licence
22

3-
**This project cannot be redistributed under an open-source licence yet. Please read
4-
this before forking, packaging or publishing it.**
3+
This project is released under the **MIT Licence** — see [`LICENSE`](LICENSE).
54

6-
## Why
5+
## Attribution
76

8-
MG4 ABRP Telemetry is a fork of
9-
[leonkernan/ABRP_Uploader](https://github.com/lkernan), written by Leon Kernan.
7+
MG4 ABRP Telemetry is a fork of Leon Kernan's `ABRP_Uploader`, and a meaningful part of
8+
the original work survives in it. The copyright line names both him and this fork's
9+
contributors, and MIT requires that notice to travel with any copy or substantial portion
10+
of the software. Keep it.
1011

11-
**The upstream repository never contained a licence file.** Under the Berne Convention,
12-
code published without a licence is *all rights reserved* by default: the author holds
13-
copyright and grants no permission to copy, modify or redistribute. GitHub's terms allow
14-
forking within GitHub, but they do not grant redistribution rights beyond that.
15-
16-
A meaningful part of this repository is still Leon Kernan's original work, so the project
17-
as a whole cannot simply be relicensed by us.
18-
19-
## What this means in practice
20-
21-
| | Status |
22-
|---|---|
23-
| Using the app on your own car | Fine |
24-
| Forking on GitHub, reading, learning from the code | Fine (GitHub ToS) |
25-
| Redistributing APKs or source outside GitHub | **Needs Leon Kernan's permission** |
26-
| Relicensing the whole project under MIT/Apache/GPL | **Needs Leon Kernan's permission** |
12+
The upstream repository carried no licence file of its own. Applying MIT here is the
13+
project owner's decision; if Leon Kernan ever objects, the right response is to honour
14+
that rather than argue about it.
2715

2816
## No warranty
2917

30-
Separately from the licensing question above, this software carries **no warranty and no
31-
liability** — see [`DISCLAIMER.md`](DISCLAIMER.md). Resolving the licence would not change
32-
that.
33-
34-
## Contributions made in this fork
35-
36-
Everything authored in this fork — the telemetry correctness work, credential handling,
37-
the vehicle-data layer changes, the cadence and UI work, the build and CI tooling — is
38-
offered by its authors under the **MIT Licence**, on the condition that the upstream
39-
portion is resolved. That offer alone is not enough to make the combined work
40-
redistributable.
41-
42-
## How to resolve this
43-
44-
1. Contact Leon Kernan and ask him to add a licence upstream (MIT is the obvious fit and
45-
matches the sibling MG4Control project), or to grant this fork an explicit licence.
46-
2. Record the outcome here, replacing this file with the agreed licence text.
47-
3. If he declines or cannot be reached, the alternative is to rewrite the remaining
48-
original code so that no upstream-copyrighted material is left, and document that.
49-
50-
Until then this file stays as it is. Publishing an MIT `LICENSE` over code we do not hold
51-
the rights to would be worse than having no licence at all — it would tell users they have
52-
permissions that nobody actually granted them.
18+
MIT disclaims all warranty and liability, and this software runs on a **vehicle** — see
19+
[`DISCLAIMER.md`](DISCLAIMER.md) for what that means concretely.

‎app/build.gradle‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ android {
5252
nightly {
5353
dimension "channel"
5454
applicationIdSuffix ".nightly"
55+
// Le numéro de build fait partie du COEUR numérique de la version
56+
// ("1.0.42-nightly"), pas du suffixe : l'updater compare des segments
57+
// numériques, donc deux nightlies doivent différer avant le premier tiret.
58+
// -PnightlyBuild=<n> est passé par la CI ; 0 en local.
59+
versionName "${defaultConfig.versionName}.${project.findProperty('nightlyBuild') ?: '0'}"
5560
versionNameSuffix "-nightly"
5661
buildConfigField "boolean", "OTA_ENABLED", "true"
5762
}
@@ -87,6 +92,14 @@ android {
8792
}
8893
}
8994

95+
// Version publiée par la CI pour composer le tag de la pré-release : le tag DOIT être
96+
// comparable par l'updater, donc "v1.0.42" et non "nightly-42".
97+
tasks.register('printNightlyVersion') {
98+
doLast {
99+
println "${android.defaultConfig.versionName}.${project.findProperty('nightlyBuild') ?: '0'}"
100+
}
101+
}
102+
90103
// Nomme les APK par canal pour que les artefacts de release soient lisibles.
91104
androidComponents {
92105
onVariants(selector().all()) { variant ->

‎app/src/nightly/java/com/mg4/abrptelemetry/OtaUpdater.java‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,22 @@ static Update check(String currentVersion) {
151151
}
152152

153153
JSONArray releases = new JSONArray(body.toString());
154+
155+
// Scan every entry and keep the HIGHEST version, not simply the first one
156+
// that beats the installed build: the API's ordering is by creation date, and
157+
// a re-published or back-dated release would otherwise win over a newer one.
158+
//
159+
// Stable releases are skipped on purpose. This channel tracks pre-releases
160+
// only — and a stable APK could not update a nightly install anyway, since
161+
// the nightly applicationId carries a .nightly suffix.
162+
Update best = null;
154163
for (int i = 0; i < releases.length(); i++) {
155164
JSONObject release = releases.getJSONObject(i);
156-
// Nightly tracks pre-releases; a stable tag is not this channel's business.
157165
if (!release.optBoolean("prerelease", false)) continue;
158166

159167
String tag = release.optString("tag_name", "");
160168
if (!isNewer(tag, currentVersion)) continue;
169+
if (best != null && !isNewer(tag, best.versionName)) continue;
161170

162171
JSONArray assets = release.optJSONArray("assets");
163172
if (assets == null) continue;
@@ -172,10 +181,11 @@ static Update check(String currentVersion) {
172181
Log.w(TAG, "Rejected update URL from an unexpected host: " + url);
173182
continue;
174183
}
175-
return new Update(tag, url);
184+
best = new Update(tag, url);
185+
break;
176186
}
177187
}
178-
return null;
188+
return best;
179189
} catch (Exception e) {
180190
Log.w(TAG, "Update check failed: " + e.getMessage());
181191
return null;

‎app/src/testNightly/java/com/mg4/abrptelemetry/OtaUpdaterTest.java‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,20 @@ public void equalOrLowerVersionsAreNotNewer() {
7171

7272
@Test
7373
public void theNightlySuffixIsIgnored() {
74-
// The installed nightly reports "1.2.0-nightly"; that must not read as older
75-
// than the "1.2.0" tag it was built from, or it would update to itself forever.
76-
assertFalse(OtaUpdater.isNewer("v1.2.0", "1.2.0-nightly"));
77-
assertTrue(OtaUpdater.isNewer("v1.2.1", "1.2.0-nightly"));
74+
// The installed nightly reports "1.0.42-nightly"; that must not read as older
75+
// than the "v1.0.42" tag it was built from, or it would update to itself forever.
76+
assertFalse(OtaUpdater.isNewer("v1.0.42", "1.0.42-nightly"));
77+
assertTrue(OtaUpdater.isNewer("v1.0.43", "1.0.42-nightly"));
78+
}
79+
80+
@Test
81+
public void nightlyBuildNumbersCompareAsVersions() {
82+
// The CI tags nightlies "v<base>.<run>" precisely so this works. A tag like
83+
// "nightly-43" parses to 0 and would never look newer than an installed build,
84+
// so the channel would silently never update.
85+
assertTrue(OtaUpdater.isNewer("v1.0.100", "1.0.99-nightly"));
86+
assertFalse(OtaUpdater.isNewer("v1.0.41", "1.0.42-nightly"));
87+
assertArrayEquals(new int[]{0}, OtaUpdater.segments("nightly-43"));
7888
}
7989

8090
@Test

0 commit comments

Comments
 (0)