diff --git a/.github/workflows/build-installer.yml b/.github/workflows/build-installer.yml
index 207eb82..49184ea 100644
--- a/.github/workflows/build-installer.yml
+++ b/.github/workflows/build-installer.yml
@@ -29,6 +29,8 @@ env:
ESP_IDF_VERSION: ${{ 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:
@@ -57,9 +59,9 @@ jobs:
secrets: inherit
update-docs-files:
- needs: build-installer-ide
+ needs: [build-installer-online, build-installer-offline, build-installer-ide]
name: Create ${{ inputs.installer_type}} installer release PR
- if: ${{ needs.build-installer-ide.result }} == 'success' || ${{ needs.build-installer-offline.result }} == 'success' || ${{ needs.build-installer-online.result }} == 'success'
+ if: ${{ always() }} && (${{ needs.build-installer-ide.result }} == 'success' || ${{ needs.build-installer-offline.result }} == 'success' || ${{ needs.build-installer-online.result }} == 'success')
runs-on: windows-latest
strategy:
fail-fast: false
@@ -78,6 +80,9 @@ jobs:
name: installer-size
path: ./
+ - name: Install script requirements
+ run: pip install -r scripts/requirements.txt
+
- name: Get size of online installer and Update docs files
run: |
echo "Instaler size from variable is $(Get-Content variables.txt)"
@@ -100,6 +105,11 @@ jobs:
run: |
Remove-Item -Path variables.txt -Force
+ - name: Put current date into a variable
+ run: |
+ $DATE=& Get-Date -format yyyy-MM-dd
+ echo "DATE=$DATE" >> $env:GITHUB_ENV
+
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
@@ -107,6 +117,7 @@ jobs:
commit-message: 'Release ${{ env.INSTALLER_TYPE }} installer ${{env.ESPRESSIF_IDE_VERSION}}${{env.ONLINE_INSTALLER_VERSION}} with ESP-IDF v${{ env.ESP_IDF_VERSION }}'
title: 'Release ${{ env.INSTALLER_TYPE }} installer ${{env.ESPRESSIF_IDE_VERSION}}${{env.ONLINE_INSTALLER_VERSION}} with ESP-IDF v${{ env.ESP_IDF_VERSION }}'
body: '- Updated docs files'
- branch: 'release-${{ env.INSTALLER_TYPE }}-installer'
+ branch: 'release-${{ env.INSTALLER_TYPE }}-installer-${{ env.DATE }}'
delete-branch: true
- base: 'main'
\ No newline at end of file
+ base: 'main'
+ reviewers: georgik, jakub-kocka
\ No newline at end of file
diff --git a/.github/workflows/build-online-installer.yml b/.github/workflows/build-online-installer.yml
index f533f97..844abe8 100644
--- a/.github/workflows/build-online-installer.yml
+++ b/.github/workflows/build-online-installer.yml
@@ -29,7 +29,7 @@ jobs:
shell: pwsh
run: .\Build-Installer.ps1 -InstallerType online
- - name: Create Release
+ - name: Create Release TODO
id: create_release
uses: actions/create-release@v1
env:
diff --git a/scripts/docs_update_release.py b/scripts/docs_update_release.py
index f976f86..95af451 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 = "./src/Resources/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 = eval(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/requirements.txt b/scripts/requirements.txt
new file mode 100644
index 0000000..38cae65
--- /dev/null
+++ b/scripts/requirements.txt
@@ -0,0 +1,2 @@
+# Template engine for creating index.html in src/Resources/download/index.html from template in scripts/templates/template_index.html
+Jinja2 ~= 3.1
\ No newline at end of file
diff --git a/src/Resources/templates/template_index.html b/src/Resources/templates/template_index.html
new file mode 100644
index 0000000..431bca6
--- /dev/null
+++ b/src/Resources/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
+
+
+
+
+
+
+
+