Skip to content

Commit f51b61b

Browse files
committed
Use GitHub API to fetch latest release tag
1 parent 3a902eb commit f51b61b

File tree

9 files changed

+198
-27
lines changed

9 files changed

+198
-27
lines changed

.github/workflows/developer-guide-docs.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,20 @@ jobs:
114114
echo "REV_HUMAN_DATE=$REV_HUMAN_DATE"
115115
} >> "$GITHUB_ENV"
116116
117+
- name: Determine Codename One release version
118+
run: |
119+
set -euo pipefail
120+
VERSION="$(python3 scripts/developer-guide/determine_release_version.py)"
121+
if [ -z "$VERSION" ]; then
122+
echo "Unable to determine Codename One release version" >&2
123+
exit 1
124+
fi
125+
echo "Using Codename One release version: $VERSION" >&2
126+
{
127+
echo "CN1_RELEASE_VERSION=$VERSION"
128+
echo "CN1_PLUGIN_RELEASE_VERSION=$VERSION"
129+
} >> "$GITHUB_ENV"
130+
117131
- name: Render publication cover artwork
118132
run: |
119133
set -euo pipefail

docs/developer-guide/About-This-Guide.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ While this guide focuses on tutorial and conceptual material, the complete API r
1717

1818
This document includes content from multiple authors and community wiki edits. If you edit pages within the guide feel free to add your name here alphabetized by surname:
1919

20-
- https://github.com/codenameone/[Shai Almog]
20+
- https://github.com/shai-almog[Shai Almog]
2121
- https://github.com/Isborg[Ismael Baum]
2222
- https://twitter.com/ericcoolmandev[Eric Coolman]
2323
- http://github.com/chen-fishbein/[Chen Fishbein]

docs/developer-guide/Index.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ IMPORTANT: Codename One doesn't send source code to the build cloud, only compil
3939

4040
The build servers allow building native iOS Apps without a Mac and native Windows apps without a Windows machine. They remove the need to install/update complex toolchains and simplify the process of building a native app to a right click.
4141

42+
Even though the build servers streamline delivery, Codename One also supports fully local builds. You can install the toolchain on your own hardware and follow the workflows in <<maven-project-workflow>> and <<working-with-codename-one-sources>> to compile, package, and test apps without leaving your desktop environment.
43+
4244
E.g.: Since building native iOS applications requires a Mac OS X machine with a recent version of xcode Codename One maintains such machines in the cloud. When developers send an iOS build such a Mac will be used to generate C source code using https://github.com/codenameone/CodenameOne/tree/master/vm[ParparVM] and it will then compile the C source code using xcode & sign the resulting binary using xcode. You can install the binary to your device or build a distribution binary for the appstore. Since C code is generated it also means that your app will be "future proof" in a case of changes from Apple. You can also inject Objective-C native code into the app while keeping it 100% portable thanks to the "native interfaces" capability of Codename One.
4345

4446
Subscribers can receive the C source code back using the include sources feature of Codename One and use those sources for benchmarking, debugging on devices etc.

docs/developer-guide/Maven-Getting-Started.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Here is an example which generates a project based on the bare-bones kotlin temp
7878

7979
[source,bash]
8080
----
81-
mvn com.codenameone:codenameone-maven-plugin:7.0.19:generate-app-project \
81+
mvn com.codenameone:codenameone-maven-plugin:{cn1-plugin-release-version}:generate-app-project \
8282
-DarchetypeGroupId=$archetypeGroupId \
8383
-DarchetypeArtifactId=$archetypeArtifactId \
8484
-DarchetypeVersion=$archetypeVersion \
@@ -96,7 +96,7 @@ Like the `archetype:generate` goal, this will create the project in a directory
9696

9797
Some notes here:
9898

99-
. The `com.codenameone:codenameone-maven-plugin:7.0.19:generate-app-project` argument is the fully-qualified goal name for the `generate-app-project`. This is necessary since we aren't running this goal in the context of any existing project. You should adjust the version number (`7.0.19`) to reflect the https://search.maven.org/search?q=a:codenameone-maven-plugin[latest available Codename One version on Maven Central].
99+
. The `com.codenameone:codenameone-maven-plugin:{cn1-plugin-release-version}:generate-app-project` argument is the fully-qualified goal name for the `generate-app-project`. This is necessary since we aren't running this goal in the context of any existing project. You should adjust the version number (`{cn1-plugin-release-version}`) to reflect the https://search.maven.org/search?q=a:codenameone-maven-plugin[latest available Codename One version on Maven Central].
100100
. The `archetypeGroupId`, `archetypeArtifactId`, and `archetypeVersion` parameters are the same as when using the `archetype:generate` goal, and they will (almost) always refer to the <<cn1app-archetype>>.
101101
. The `groupId`, `artifactId`, and `version` work the same as for the `archetype:generate` goal. That is, that they specify the coordinates for your newly created project.
102102
. The `mainName` specifies the Main class name for your app. This is just the class name, and should not include the full package. E.g. "MyApp", not "com.example.MyApp"
@@ -121,7 +121,7 @@ A minimal invocation of this goal would look like:
121121
# Specify your the version of the codenameone-maven-plugin.
122122
# Find the latest version at
123123
# https://search.maven.org/search?q=a:codenameone-maven-plugin
124-
CN1VERSION=7.0.19
124+
CN1VERSION={cn1-plugin-release-version}
125125
mvn com.codenameone:codenameone-maven-plugin:$CN1VERSION:generate-app-project \
126126
-DgroupId=YOUR_GROUP_ID \
127127
-DartifactId=YOUR_ARTIFACT_ID \
@@ -212,7 +212,7 @@ The following is a bash script that uses curl to download this project as a zip
212212

213213
[source,bash]
214214
----
215-
CN1_VERSION=7.0.19
215+
CN1_VERSION={cn1-plugin-release-version}
216216
curl -L https://github.com/codenameone/KitchenSink/archive/v1.0-cn7.0.11.zip > master.zip
217217
unzip master.zip
218218
rm master.zip

docs/developer-guide/Maven-Project-Workflow.asciidoc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,5 @@ include::Maven-Getting-Started.adoc[leveloffset=+1]
88
include::Maven-Updating-Codename-One.adoc[leveloffset=+1]
99
include::Maven-Project-Templates.adoc[leveloffset=+1]
1010
include::Maven-Creating-CN1Libs.adoc[leveloffset=+1]
11-
include::Maven-Appendix-Archetypes.adoc[leveloffset=+1]
12-
include::Maven-Appendix-Goals.adoc[leveloffset=+1]
13-
include::Maven-Appendix-API.adoc[leveloffset=+1]
14-
include::Maven-Appendix-Control-Center.adoc[leveloffset=+1]
15-
include::Maven-Appendix-Rich-Properties.adoc[leveloffset=+1]
11+
12+
// The detailed Maven appendices now live alongside the other appendices at the end of the guide.

docs/developer-guide/Maven-Updating-Codename-One.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ E.g. Open the `pom.xml` file, and look for the following:
5050

5151
[source,xml]
5252
----
53-
<cn1.plugin.version>7.0.19</cn1.plugin.version>
54-
<cn1.version>7.0.19</cn1.version>
53+
<cn1.plugin.version>{cn1-plugin-release-version}</cn1.plugin.version>
54+
<cn1.version>{cn1-release-version}</cn1.version>
5555
----
5656

5757
Change these values to reflect the latest version of the `codenameone-maven-plugin` found https://search.maven.org/artifact/com.codenameone/codenameone-maven-plugin[here].

docs/developer-guide/Working-With-CodenameOne-Sources.asciidoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ project), adjust the `pom.xml` properties to reference your snapshot version:
8181
----
8282
<properties>
8383
<!-- Replace with the snapshot printed during mvn install -->
84-
<cn1.version>7.0.21-SNAPSHOT</cn1.version>
85-
<cn1.plugin.version>7.0.21-SNAPSHOT</cn1.plugin.version>
84+
<cn1.version>{cn1-snapshot-version}</cn1.version>
85+
<cn1.plugin.version>{cn1-snapshot-version}</cn1.plugin.version>
8686
</properties>
8787
----
8888

docs/developer-guide/developer-guide.asciidoc

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@
2828
:copyright: Codename One, all rights reserved
2929
:publication-type: book
3030
:producer: Codename One Ltd.
31-
:partnums:
31+
:cn1-release-version: {env:CN1_RELEASE_VERSION}
32+
ifeval::["{cn1-release-version}" == ""]
33+
:cn1-release-version: 7.0.21
34+
endif::[]
35+
36+
:cn1-plugin-release-version: {env:CN1_PLUGIN_RELEASE_VERSION}
37+
ifeval::["{cn1-plugin-release-version}" == ""]
38+
:cn1-plugin-release-version: {cn1-release-version}
39+
endif::[]
40+
41+
:cn1-snapshot-version: {cn1-release-version}-SNAPSHOT
3242

3343
= {doctitle}
3444
{author}
@@ -37,12 +47,8 @@ toc::[]
3747

3848
include::About-This-Guide.asciidoc[]
3949

40-
= Part I. Project Setup
41-
4250
include::Maven-Project-Workflow.asciidoc[]
4351

44-
= Part II. Foundations
45-
4652
include::Index.asciidoc[]
4753

4854
include::basics.asciidoc[]
@@ -53,8 +59,6 @@ include::Advanced-Theming.asciidoc[]
5359

5460
include::css.asciidoc[]
5561

56-
= Part III. User Interface and Experience
57-
5862
include::The-Components-Of-Codename-One.asciidoc[]
5963

6064
include::Animations.asciidoc[]
@@ -63,8 +67,6 @@ include::The-EDT---Event-Dispatch-Thread.asciidoc[]
6367

6468
include::graphics.asciidoc[]
6569

66-
= Part IV. Application Services
67-
6870
include::Events.asciidoc[]
6971

7072
include::io.asciidoc[]
@@ -77,8 +79,6 @@ include::performance.asciidoc[]
7779

7880
include::Monetization.asciidoc[]
7981

80-
= Part V. Platform and Deployment
81-
8282
include::Advanced-Topics-Under-The-Hood.asciidoc[]
8383

8484
include::security.asciidoc[]
@@ -91,10 +91,18 @@ include::Working-With-Javascript.asciidoc[]
9191

9292
include::Working-with-Mac-OS-X.asciidoc[]
9393

94-
= Part VI. Contributing and Appendices
95-
9694
include::Working-With-CodenameOne-Sources.asciidoc[]
9795

96+
include::Maven-Appendix-Archetypes.adoc[]
97+
98+
include::Maven-Appendix-Goals.adoc[]
99+
100+
include::Maven-Appendix-API.adoc[]
101+
102+
include::Maven-Appendix-Control-Center.adoc[]
103+
104+
include::Maven-Appendix-Rich-Properties.adoc[]
105+
98106
= Historical Reference
99107

100108
include::Working-with-UWP.asciidoc[]
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env python3
2+
"""Determine the current Codename One release version for documentation builds."""
3+
from __future__ import annotations
4+
5+
import json
6+
import os
7+
import re
8+
import subprocess
9+
import sys
10+
import xml.etree.ElementTree as ET
11+
from pathlib import Path
12+
from typing import Iterable, List
13+
from urllib.error import HTTPError, URLError
14+
from urllib.request import Request, urlopen
15+
16+
17+
def _sanitize_tag(value: str) -> str:
18+
value = value.strip()
19+
if value.lower().startswith("refs/tags/"):
20+
value = value[10:]
21+
if value.lower().startswith("tags/"):
22+
value = value[5:]
23+
if value and value[0] in {"v", "V"} and value[1:2].isdigit():
24+
value = value[1:]
25+
return value.strip()
26+
27+
28+
def _parse_version_components(version: str) -> List[int]:
29+
return [int(part) for part in version.split(".")]
30+
31+
32+
def release_tag_from_event() -> str:
33+
event_path = os.environ.get("GITHUB_EVENT_PATH")
34+
if event_path:
35+
event_file = Path(event_path)
36+
if event_file.is_file():
37+
try:
38+
data = json.loads(event_file.read_text())
39+
except json.JSONDecodeError:
40+
data = {}
41+
release = data.get("release") or {}
42+
tag = release.get("tag_name") or release.get("target_commitish") or ""
43+
if tag:
44+
return _sanitize_tag(tag)
45+
for key in ("GITHUB_REF_NAME", "GITHUB_REF"):
46+
value = os.environ.get(key)
47+
if value:
48+
sanitized = _sanitize_tag(value)
49+
if sanitized:
50+
return sanitized
51+
return ""
52+
53+
54+
def latest_release_from_api() -> str:
55+
repository = os.environ.get("GITHUB_REPOSITORY")
56+
if not repository:
57+
return ""
58+
api_base = os.environ.get("GITHUB_API_URL", "https://api.github.com")
59+
url = f"{api_base.rstrip('/')}/repos/{repository}/releases/latest"
60+
headers = {
61+
"Accept": "application/vnd.github+json",
62+
"User-Agent": "codenameone-docs-release-version",
63+
}
64+
token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
65+
if token:
66+
headers["Authorization"] = f"Bearer {token}"
67+
request = Request(url, headers=headers)
68+
try:
69+
with urlopen(request, timeout=10) as response:
70+
if response.status != 200:
71+
return ""
72+
try:
73+
payload = json.load(response)
74+
except json.JSONDecodeError:
75+
return ""
76+
except (HTTPError, URLError, TimeoutError):
77+
return ""
78+
tag = payload.get("tag_name")
79+
if not tag:
80+
return ""
81+
return _sanitize_tag(str(tag))
82+
83+
84+
def latest_git_tag() -> str:
85+
try:
86+
subprocess.run(
87+
["git", "fetch", "--tags", "--force"],
88+
check=True,
89+
stdout=subprocess.PIPE,
90+
stderr=subprocess.PIPE,
91+
)
92+
except (subprocess.CalledProcessError, FileNotFoundError):
93+
pass
94+
try:
95+
result = subprocess.run(
96+
["git", "tag", "--list", "v*"],
97+
check=True,
98+
stdout=subprocess.PIPE,
99+
stderr=subprocess.PIPE,
100+
text=True,
101+
)
102+
except (subprocess.CalledProcessError, FileNotFoundError):
103+
return ""
104+
tags: Iterable[str] = (_sanitize_tag(line) for line in result.stdout.splitlines())
105+
numeric_tags = [tag for tag in tags if re.fullmatch(r"\d+(?:\.\d+)*", tag)]
106+
if not numeric_tags:
107+
return ""
108+
numeric_tags.sort(key=_parse_version_components)
109+
return numeric_tags[-1]
110+
111+
112+
def version_from_pom(root: Path) -> str:
113+
pom_path = root / "maven" / "pom.xml"
114+
if not pom_path.is_file():
115+
return ""
116+
try:
117+
tree = ET.parse(pom_path)
118+
except ET.ParseError:
119+
return ""
120+
namespace = {"mvn": "http://maven.apache.org/POM/4.0.0"}
121+
version_element = tree.getroot().find("mvn:version", namespace)
122+
if version_element is None:
123+
return ""
124+
version = (version_element.text or "").strip()
125+
if not version:
126+
return ""
127+
if version.endswith("-SNAPSHOT"):
128+
version = version[: -len("-SNAPSHOT")]
129+
return version
130+
131+
132+
def main() -> int:
133+
repo_root = Path(__file__).resolve().parents[2]
134+
135+
for candidate in (release_tag_from_event, latest_release_from_api, latest_git_tag):
136+
version = candidate()
137+
if version:
138+
print(version)
139+
return 0
140+
141+
version = version_from_pom(repo_root)
142+
if version:
143+
print(version)
144+
return 0
145+
146+
return 1
147+
148+
149+
if __name__ == "__main__":
150+
sys.exit(main())

0 commit comments

Comments
 (0)