diff --git a/.github/workflows/build-installer.yml b/.github/workflows/build-installer.yml
index 207eb82..ca32485 100644
--- a/.github/workflows/build-installer.yml
+++ b/.github/workflows/build-installer.yml
@@ -23,18 +23,22 @@ on:
description: 'Online Installer version (e.g. 2.0)'
required: false
default: ''
+ pull_request: # TODO
env:
- INSTALLER_TYPE: ${{ inputs.installer_type }}
- ESP_IDF_VERSION: ${{ inputs.esp_idf_version }}
+ # TODO not constants!
+ INSTALLER_TYPE: "offline" #${{ inputs.installer_type }}
+ ESP_IDF_VERSION: "4.4.7" #${{ inputs.esp_idf_version }}
ESPRESSIF_IDE_VERSION: ${{ inputs.espressif_ide_version }}
ONLINE_INSTALLER_VERSION: ${{ inputs.online_installer_version }}
+ # Based on this defined supported IDF versions are created installer buttons in index.html from releases.json
+ SUPPORTED_IDF_VERSIONS: ("5.2", "4.4", "5.1", "5.0")
jobs:
build-installer-online:
name: Build Online Installer
if: ${{ inputs.installer_type }} == 'online'
- uses: espressif/idf-installer/.github/workflows/build-online-installer.yml@main
+ uses: espressif/idf-installer/.github/workflows/build-online-installer.yml@feat/automatic_installer_release #TODO
with:
online_installer_version: ${{ inputs.online_installer_version }}
secrets: inherit
@@ -42,7 +46,7 @@ jobs:
build-installer-offline:
name: Build Offline Installer
if: ${{ inputs.installer_type }} == 'offline'
- uses: espressif/idf-installer/.github/workflows/build-offline-installer.yml@main
+ uses: espressif/idf-installer/.github/workflows/build-offline-installer.yml@feat/automatic_installer_release #TODO
with:
esp_idf_version: ${{ inputs.esp_idf_version}}
secrets: inherit
@@ -50,7 +54,7 @@ jobs:
build-installer-ide:
name: Build IDE Installer
if: ${{ inputs.installer_type }} == 'espressif-ide'
- uses: espressif/idf-installer/.github/workflows/build-espressif-ide-installer.yml@main
+ uses: espressif/idf-installer/.github/workflows/build-espressif-ide-installer.yml@feat/automatic_installer_release #TODO
with:
esp_idf_version: ${{ inputs.esp_idf_version }}
espressif_ide_version: ${{ inputs.espressif_ide_version }}
diff --git a/scripts/docs_update_release.py b/scripts/docs_update_release.py
index f976f86..4041d28 100644
--- a/scripts/docs_update_release.py
+++ b/scripts/docs_update_release.py
@@ -5,129 +5,97 @@
from datetime import date
+from jinja2 import Template, StrictUndefined
+
# Global constants with paths for files to be changed
RELEASES_JSON_PATH = "./src/Resources/download/releases.json"
INDEX_PATH = "./src/Resources/download/index.html"
INNO_SETUP_PATH = "./src/InnoSetup/IdfToolsSetup.iss"
+INDEX_TEMPLATE_PATH = "./scripts/templates/template_index.html"
-# Environment variables from GitHub Actions (environmental variables of the runner)
-installer_type: str = environ.get('INSTALLER_TYPE', '') # espressif-ide, offline, online
-installer_size: str = argv[1] # e.g. '1.69 GB'
-idf_version = environ.get('ESP_IDF_VERSION', '') # e.g. '4.4.7'
-ide_version = environ.get('ESPRESSIF_IDE_VERSION', '') # e.g. '2.13.69'
-online_installer_version = environ.get('ONLINE_INSTALLER_VERSION', '') # e.g. '2.25'
-
-
-def _resolve_installer_type(new_idf_version: str) -> str:
- """Resolve the type of the installer
- and return the string of new entry for the index.html
- """
- new_entry_ide = f"""
"""
-
- new_entry_offline = f""" """
-
- new_entry_online = f""" """
-
- """ Installer types acquired from environmental variable of the runner - the same names as with the tags used
- (No possible way to choose different type - list of options in workflow)
- """
- if installer_type == 'espressif-ide':
- return new_entry_ide
- elif installer_type == 'offline':
- return new_entry_offline
- elif installer_type == 'online':
- return new_entry_online
-
-
-def update_index(new_idf_version: str):
- """Update the index.html file with the new release of the installer"""
- try:
- with open(path.abspath(INDEX_PATH), "r") as index_file:
- index_lines = index_file.readlines()
- except FileNotFoundError as e:
- raise SystemExit(f"Error opening file {INDEX_PATH} - {e}")
-
- # find every element with the class "download-button"
- elements = []
- for i, line in enumerate(index_lines):
- if line.strip() == '':
- elements.append([i, index_lines[i:i+10]]) # TODO guess the number dynamically ... regex probably
- i += 10 # skip the next 10 lines (the length of the element with the class "download-button")
-
- # choose the elements that contain the installer type
- selected_elements = []
- for element in elements:
- if any(f'{installer_type}' in element_line for element_line in element[1]):
- selected_elements.append(element)
-
- print(f"Found {len(selected_elements)} elements with the installer type {installer_type}")
-
+class AddedInstallers:
+ """This class stores if all installer types for all supported versions have been added"""
+ def __init__(self, supported_idf_versions):
+ self.online = False
+ self.offline = False
+ self.espressif_ide = False
- def _replace_installer_button(element_to_replace:list) -> str:
- """Replace the first occurrence of the installer button with the new one"""
- element_to_replace = ''.join(element_to_replace[1])
- print(f"This element will be replaced:\n{element_to_replace}")
+ self.supported_idf_versions = supported_idf_versions
+
+ def all_added(self):
+ """Check if all installer objects for buttons have been added"""
+ return self.online and self.offline and self.espressif_ide and len(self.supported_idf_versions) == 0
- index_data = ''.join(index_lines)
- return index_data.replace(element_to_replace, _resolve_installer_type(new_idf_version))
-
- # replace the first occurrence of the offline installer button
- if installer_type == 'offline':
- element_to_replace = None
- for selected_element in selected_elements:
- for element_line in selected_element[1]:
- if f'{idf_version[0]}.{idf_version[1]}' in element_line:
- element_to_replace = selected_element
+def update_index(releases, supported_idf_versions):
+ """Update the index.html file with the new release of the installer"""
+ added_installers = AddedInstallers(supported_idf_versions)
+
+ online = None
+ espressif_ide = None
+ offline = []
+ for release in releases:
+ if added_installers.all_added():
+ break
+
+ if release['type'] == 'online' and not added_installers.online:
+ online = release
+ added_installers.online = True
+
+ if release['type'] == 'espressif-ide' and not added_installers.espressif_ide:
+ espressif_ide = release
+ added_installers.espressif_ide = True
+
+ if release['type'] == 'offline' and not added_installers.offline:
+ for version in added_installers.supported_idf_versions:
+ if version in release['version']:
+ offline.append(release)
+ added_installers.supported_idf_versions.remove(version)
break
- if element_to_replace:
- new_index_data = _replace_installer_button(element_to_replace)
- else: # add new installer button to the top of the offline installer buttons
- first_occurrence = selected_elements[0][0]
+ if len(added_installers.supported_idf_versions) == 0:
+ added_installers.offline = True
- print(f"First occurrence on line {first_occurrence} - adding new installer button here")
- index_data = index_lines[0:first_occurrence-1] + list(_resolve_installer_type(new_idf_version)+'\n') + index_lines[first_occurrence:]
- new_index_data = ''.join(index_data)
- else: # replace the first occurrence of the other installer type button
- new_index_data = _replace_installer_button(selected_elements[0])
+ # sort for offline installer objects for buttons
+ offline_sorted = sorted(offline, key=lambda item: item['version'], reverse=True)
+ try:
+ with open(INDEX_TEMPLATE_PATH, 'r') as f:
+ template = f.read()
+ except FileNotFoundError as e:
+ raise SystemExit(f"Error reading file {INDEX_TEMPLATE_PATH} - {e}")
+
+ # StrictUndefined will rise an error if any variable in template is not passed
+ # (instead of silent replace as an empty string)
+ j2_template = Template(template, undefined=StrictUndefined)
+
+ # regex for finding IDE and IDF version in 'version' of espressif_ide object (PATCH part not mandatory)
+ # "2.12.0-with-esp-idf-5.1" -> ['2.12.0', '5.1']
+ pattern = r'\b(\d+\.\d+(?:\.\d+)?)\b'
+ ide_version, ide_idf = re.findall(pattern, espressif_ide['version'])
+
+ # variables to be changed in index.html
+ variables = {
+ "online":{
+ "version": online['version'],
+ "size": online['size'],
+ },
+ "espressif_ide":{
+ "version": ide_version,
+ "idf_version": ide_idf,
+ "size": espressif_ide['size'],
+ },
+ "offline_buttons": offline_sorted
+ }
try:
with open(path.abspath(INDEX_PATH), "w") as index_file:
- index_file.write(new_index_data)
+ index_file.write(j2_template.render(variables))
except FileNotFoundError as e:
raise SystemExit(f"Error writing file {INDEX_PATH} - {e}")
-def update_releases_json(new_idf_version: str):
+def update_releases_json(new_idf_version: str, installer_type: str, online_installer_version: str, installer_size: str):
"""Update the releases.json file with the new release of the installer"""
try:
with open(path.abspath(RELEASES_JSON_PATH), "r") as releases_file:
@@ -152,9 +120,11 @@ def update_releases_json(new_idf_version: str):
json.dump(releases_json, releases_file, indent=4)
except FileNotFoundError as e:
raise SystemExit(f"Error writing file {RELEASES_JSON_PATH} - {e}")
+
+ return releases_json
-def update_inno_setup():
+def update_inno_setup(installer_type: str, online_installer_version: str, ide_version: str):
"""Update the version of the installer in the InnoSetup file"""
try:
with open(path.abspath(INNO_SETUP_PATH), "r") as inno_setup_file:
@@ -179,6 +149,16 @@ def main():
"""Performs the update of all necessary files for the new release of the installer"""
if len(argv) < 2:
raise SystemExit("ERROR: Installer size is not passed as an argument")
+
+ # Environment variables from GitHub Actions (environmental variables of the runner)
+ installer_type: str = environ.get('INSTALLER_TYPE', '') # espressif-ide, offline, online
+ installer_size: str = argv[1] # e.g. '1.69 GB'
+ idf_version = environ.get('ESP_IDF_VERSION', '') # e.g. '4.4.7'
+ ide_version = environ.get('ESPRESSIF_IDE_VERSION', '') # e.g. '2.13.69'
+ online_installer_version = environ.get('ONLINE_INSTALLER_VERSION', '') # e.g. '2.25'
+
+ supported_idf_versions = environ.get('SUPPORTED_IDF_VERSIONS', ('5.2', '4.4', '5.1', '5.0')) # e.g. ('5.2', '4.4', '5.1', '5.0')
+ supported_idf_versions = list(supported_idf_versions)
if not idf_version:
raise SystemExit("ERROR: IDF version is not provided")
@@ -196,10 +176,10 @@ def main():
new_idf_version = f"{idf_version[0]}.{idf_version[1]}{f'.{idf_version[2]}' if idf_version[2] else ''}"
if ide_version and not re.match(r'(\d+\.\d+\.\d+)', ide_version):
- raise SystemExit(f"ERROR: IDE version is not in correct format (it should be 'X.Y.Z')")
+ raise SystemExit(f"ERROR: IDE version is not in correct format (it should be 'X.Y.Z') which '{ide_version}' is not")
if online_installer_version and not re.match(r'(\d+\.\d+)', online_installer_version):
- raise SystemExit(f"ERROR: Online installer version is not in correct format (it should be 'X.Y')")
+ raise SystemExit(f"ERROR: Online installer version is not in correct format (it should be 'X.Y') which '{online_installer_version}' is not")
if installer_type == 'online' and online_installer_version == '':
raise SystemExit(f"ERROR: online_installer_version is not provided")
@@ -207,13 +187,13 @@ def main():
if installer_type == 'espressif-ide' and ide_version == '':
raise SystemExit(f"ERROR: esp_ide_version or espressif_ide_version is not provided")
- update_releases_json(new_idf_version)
+ releases_json = update_releases_json(new_idf_version, installer_type, online_installer_version, installer_size)
# Update App or IDE version if the installer type is not offline
if installer_type != 'offline':
- update_inno_setup()
+ update_inno_setup(installer_type, online_installer_version, ide_version)
- update_index(new_idf_version)
+ update_index(releases_json, supported_idf_versions)
print("Files update done!")
diff --git a/scripts/templates/template_index.html b/scripts/templates/template_index.html
new file mode 100644
index 0000000..431bca6
--- /dev/null
+++ b/scripts/templates/template_index.html
@@ -0,0 +1,266 @@
+
+
+
+
+
+
+
+
+
+
ESP-IDF Windows Installer Download
+
Open Source IoT Development Framework for ESP32
+
+ {# Download buttons are updated according to releases.json by index_updater.py script #}
+ {# LATEST RELEASES (online and espressif_ide) ARE CONSIDERED THE MOST TOP ONES OF THE FILE #}
+ {# offline installer releases are automatically sorted and displayed buttons are BASED on SUPPORTED_IDF_VERSIONS variable in workflow #}
+
+
+
+
+ {% for button in offline_buttons %}
+
+ {% endfor %}
+
+
+
+
+
+
+
Want new installer features sooner?
+
+
+
+
+
Download links to available releases and mirrors.
+
+
+
+ Release version
+ Release date
+
+ Release notes
+
+
+
+
+
+
+
+