Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding building of v2 UI #487

Merged
merged 21 commits into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
84af72a
Updates to allow the v2 UI (or any other UI) to override the default GUI
jeremypoulter Nov 20, 2022
c0de5df
Updated to build with both v1 and v2 UI
jeremypoulter Nov 20, 2022
e64c20b
Updates to allow the v2 UI (or any other UI) to override the default GUI
jeremypoulter Nov 20, 2022
355eb5c
Updated to build with both v1 and v2 UI
jeremypoulter Nov 20, 2022
fa74fe4
Updated cheked in GUI after build script update
jeremypoulter Nov 20, 2022
174e679
Merge branch 'master' of github.com:OpenEVSE/ESP32_WiFi_V3.x into bui…
jeremypoulter Dec 19, 2022
2b70c71
Merge branch 'build_v2_gui' of github.com:OpenEVSE/ESP32_WiFi_V3.x in…
jeremypoulter Dec 19, 2022
71e2a1d
A few tweeks to actually load the new UI
jeremypoulter Dec 19, 2022
acbea13
Merge branch 'master' of github.com:OpenEVSE/ESP32_WiFi_V3.x into bui…
jeremypoulter Dec 21, 2022
aad6f18
missing mime types
KipK Dec 21, 2022
c1ee26f
Merge pull request #503 from KipK/ui2Build
jeremypoulter Dec 21, 2022
6c4547c
Enable checking the Github version action checking
jeremypoulter Jan 5, 2023
d821c53
Testing adding inputs to the manual trigger
jeremypoulter Jan 5, 2023
5cfa020
fix #505 missing claims _version init
KipK Jan 3, 2023
1a3751e
fix 505
KipK Jan 6, 2023
bb85143
Updated to create a 'release' for the v2 builds
jeremypoulter Jan 7, 2023
09dd479
Adding some debug
jeremypoulter Jan 7, 2023
4668b90
Changed to use `github.ref_name`, hopefully will get the branch name …
jeremypoulter Jan 7, 2023
068cd90
PRs need to use github.head_ref
jeremypoulter Jan 7, 2023
52ff05b
When manually triggered it is the ref_name that is build_v2_gui
jeremypoulter Jan 8, 2023
d98e8b7
Merge branch 'master' of github.com:OpenEVSE/ESP32_WiFi_V3.x into bui…
jeremypoulter Jan 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ updates:
- "jeremypoulter"
- "glynhudson"
- "chris1howell"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "jeremypoulter"
- "glynhudson"
- "chris1howell"
62 changes: 51 additions & 11 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,34 @@ name: Build/Release OpenEVSE

on:
workflow_dispatch:
inputs:
v1_ref:
required: true
description: The branch/tag for the v1 UI
default: master
v2_ref:
required: true
description: The branch/tag for the v2 UI
default: master

push:
branches:
- master
pull_request:

jobs:
debug:
runs-on: ubuntu-latest
steps:
- name: Dump the environment
run: echo "Environment variables:" && env | sort

- name: Dump the event
run: cat $GITHUB_EVENT_PATH

- name: Dump github.ref_name
run: echo "github.ref_name = '${{ github.ref_name }}'"

build:
runs-on: ubuntu-latest

Expand All @@ -31,21 +53,36 @@ jobs:
- openevse_esp32-gateway-f_dev
- openevse_esp32-poe-iso
- openevse_esp32-heltec-wifi-lora-v2
gui:
- name: openevse_wifi_gui
repo: OpenEVSE/openevse_wifi_gui
build_flags: ""
ref: ${{ inputs.v1_ref }}
- name: openevse-gui-v2
repo: KipK/openevse-gui-v2
build_flags: "-D DISABLE_WIFI_PORTAL -D WEB_SERVER_ROOT_PAGE_INDEX"
ref: ${{ inputs.v2_ref }}

steps:
- uses: ammaraskar/gcc-problem-matcher@master

- uses: actions/checkout@v2
with:
submodules: recursive
- uses: actions/checkout@v3

# - name: Temp checkout latest OpenEVSE lib
# uses: actions/checkout@v2
# uses: actions/checkout@v3
# with:
# repository: jeremypoulter/OpenEVSE_Lib
# ref: openevse_wifi_timer_apis
# path: lib/OpenEVSE

- name: Checkout GUI
uses: actions/checkout@v3
with:
repository: ${{ matrix.gui.repo }}
path: ${{ matrix.gui.name }}
ref: ${{ matrix.gui.ref }}
submodules: recursive

- name: Cache pip
uses: actions/cache@v2
with:
Expand Down Expand Up @@ -73,31 +110,34 @@ jobs:
- name: Set up Node JS
uses: actions/setup-node@v2
with:
node-version: '12'
node-version: '16'

- name: Install dependencies
run: |
cd gui
cd ${{ matrix.gui.name }}
npm install

- name: Build GUI
run: |
cd gui
cd ${{ matrix.gui.name }}
npm run build

- name: Run PlatformIO
run: pio run -e ${{ matrix.env }}
env:
GUI_NAME: ${{ matrix.gui.name }}
PLATFORMIO_BUILD_FLAGS: ${{ matrix.gui.build_flags }}

- name: Upload output to GitHub
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.env }}.bin
name: ${{ matrix.env }}_${{ matrix.gui.name }}.bin
path: .pio/build/${{ matrix.env }}/firmware.bin

release:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/master'
if: github.ref_name == 'master' || github.ref_name == 'build_v2_gui' || github.head_ref == 'build_v2_gui'

steps:
- name: Download the built assets
Expand All @@ -118,8 +158,8 @@ jobs:
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
automatic_release_tag: "${{ github.ref_name == 'master' && 'latest' || 'v2_gui' }}"
prerelease: true
title: "Development Build"
title: "${{ github.ref_name == 'master' && 'Development Build' || 'V2 GUI pre-release' }}"
files: |
*.bin
116 changes: 82 additions & 34 deletions scripts/extra_script.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from os.path import join, isfile, isdir, basename
from os import listdir, system
from os import listdir, system, environ
from pprint import pprint
import hashlib
import pathlib

Import("env")

# Dump construction environment (for debug purpose)
#print(env.Dump())

# Install pre-requisites
npm_installed = (0 == system("npm --version"))

Expand All @@ -22,8 +26,12 @@ def text_to_header(source_file):
original = source_fh.read()
filename = get_c_name(source_file)
output = "static const char CONTENT_{}[] PROGMEM = ".format(filename)
for line in original.splitlines():
output += u"\n \"{}\\n\"".format(line.replace('\\', '\\\\').replace('"', '\\"'))
lines = original.splitlines()
if len(lines) > 0:
for line in lines:
output += u"\n \"{}\\n\"".format(line.replace('\\', '\\\\').replace('"', '\\"'))
else:
output += "\"\""
output += ";\n"
output += "static const char CONTENT_{}_ETAG[] PROGMEM = \"{}\";\n".format(filename, hashlib.sha256(original.encode('utf-8')).hexdigest())
return output
Expand Down Expand Up @@ -56,55 +64,90 @@ def data_to_header(env, target, source):
for source_file in source:
#print("Reading {}".format(source_file))
file = source_file.get_abspath()
if file.endswith(".css") or file.endswith(".js") or file.endswith(".htm") or file.endswith(".html") or file.endswith(".svg") or file.endswith(".json"):
output += text_to_header(file)
if file.endswith(".css") or file.endswith(".js") or file.endswith(".htm") or file.endswith(".html") or file.endswith(".svg") or file.endswith(".json") or file.endswith(".webmanifest"): output += text_to_header(file)
else:
output += binary_to_header(file)
target_file = target[0].get_abspath()
print("Generating {}".format(target_file))
with open(target_file, "w") as output_file:
output_file.write(output)

def make_static(env, target, source):
output = ""

def filtered_listdir_scan(dir):
out_files = []
for file in listdir(dist_dir):
if isfile(join(dist_dir, file)) and (file.endswith(".gz") or file.endswith(".png") or file.endswith(".jpg")):
out_files.append(file)
for file in listdir(dir):
path = join(dir, file)
if isfile(path) and (pathlib.Path(file).suffix in (".html", ".js", ".css", ".json", ".gz", ".png", ".jpg", ".ico", ".woff", ".woff2", ".webmanifest")): out_files.append(path)
elif isdir(path):
out_files.extend(filtered_listdir_scan(path))

return out_files

def filtered_listdir(dir):
files = filtered_listdir_scan(dir)

# Sort files to make sure the order is constant
out_files = sorted(out_files)
files = sorted(files)

# filter out and GZipped files
out_files = []
for file in files:
if file.endswith(".gz") or file+".gz" not in files:
file = file.replace(join(dir, ""), "")
out_files.append(file)

return out_files

def make_safe(file):
chars = "\\/`*{}[]()>#+-.!$"
for c in chars:
if c in file:
file = file.replace(c, "_")

return file

def make_static(env, target, source):
output = ""

out_files = filtered_listdir(dist_dir)

# include the files
for out_file in out_files:
filename = "web_server."+out_file+".h"
filename = "web_server."+make_safe(out_file)+".h"
output += "#include \"{}\"\n".format(filename)

output += "StaticFile staticFiles[] = {\n"

for out_file in out_files:
filetype = None
compress = True
if out_file.endswith(".css.gz"):
compress = out_file.endswith(".gz")
if out_file.endswith(".css") or out_file.endswith(".css.gz"):
filetype = "CSS"
elif out_file.endswith(".js.gz"):
elif out_file.endswith(".js") or out_file.endswith(".js.gz"):
filetype = "JS"
elif out_file.endswith(".htm.gz") or out_file.endswith(".html.gz"):
elif out_file.endswith(".htm") or out_file.endswith(".html") or out_file.endswith(".htm.gz") or out_file.endswith(".html.gz"):
filetype = "HTML"
elif out_file.endswith(".jpg"):
filetype = "JPEG"
compress = False
elif out_file.endswith(".png"):
filetype = "PNG"
compress = False
elif out_file.endswith(".svg.gz"):
elif out_file.endswith(".ico"):
filetype = "ICO"
elif out_file.endswith(".svg") or out_file.endswith(".svg.gz"):
filetype = "SVG"
elif out_file.endswith(".json.gz"):
elif out_file.endswith(".json") or out_file.endswith(".json.gz"):
filetype = "JSON"

c_name = get_c_name(out_file)
output += " { \"/"+out_file.replace(".gz","")+"\", CONTENT_"+c_name+", sizeof(CONTENT_"+c_name+") - 1, _CONTENT_TYPE_"+filetype+", CONTENT_"+c_name+"_ETAG, "+("true" if compress else "false")+" },\n"
elif out_file.endswith(".woff"):
filetype = "WOFF"
elif out_file.endswith(".woff2"):
filetype = "WOFF2"
elif out_file.endswith(".webmanifest"):
filetype = "MANIFEST"

if filetype is not None:
c_name = get_c_name(out_file)
output += " { \"/"+out_file.replace(".gz","")+"\", CONTENT_"+c_name+", sizeof(CONTENT_"+c_name+") - 1, _CONTENT_TYPE_"+filetype+", CONTENT_"+c_name+"_ETAG, "+("true" if compress else "false")+" },\n"
else:
print("Warning: Could not detect filetype for %s" % (out_file))

output += "};\n"

Expand All @@ -117,12 +160,13 @@ def process_html_app(source, dest, env):
web_server_static_files = join(dest, "web_server_static_files.h")
web_server_static = join("$BUILDSRC_DIR", "web_server_static.cpp.o")

for file in sorted(listdir(source)):
if isfile(join(source, file)) and (file.endswith(".gz") or file.endswith(".png") or file.endswith(".jpg")):
data_file = join(source, file)
header_file = join(dest, "web_server."+file+".h")
env.Command(header_file, data_file, data_to_header)
env.Depends(web_server_static_files, header_file)
files = filtered_listdir(source)

for file in files:
data_file = join(source, file)
header_file = join(dest, "web_server."+make_safe(file)+".h")
env.Command(header_file, data_file, data_to_header)
env.Depends(web_server_static_files, header_file)

env.Depends(web_server_static, env.Command(web_server_static_files, source, make_static))

Expand All @@ -132,7 +176,11 @@ def process_html_app(source, dest, env):
if npm_installed:
headers_src = join(env.subst("$PROJECTSRC_DIR"), "web_static")

gui_dir = join(env.subst("$PROJECT_DIR"), "gui")
gui_name = environ.get("GUI_NAME")
if gui_name in (None, ""):
gui_name = "gui"

gui_dir = join(env.subst("$PROJECT_DIR"), gui_name)
dist_dir = join(gui_dir, "dist")
node_modules = join(gui_dir, "node_modules")

Expand All @@ -143,11 +191,11 @@ def process_html_app(source, dest, env):
if(isdir(dist_dir)):
process_html_app(dist_dir, headers_src, env)
else:
print("Warning: GUI not built, run 'cd %s; npm run build'" % gui_dir)
print("Warning: GUI not built, run 'cd %s; npm run build'" % (gui_dir))
else:
print("Warning: GUI dependencies not found, run 'cd %s; npm install'" % gui_dir)
print("Warning: GUI dependencies not found, run 'cd %s; npm install'" % (gui_dir))
else:
print("Warning: GUI files not found, run 'git submodule update --init'")
print("Warning: GUI files not found, run 'git submodule update --init' (%s)" % (gui_dir))
else:
print("Warning: Node.JS and NPM required to update the UI")

Expand Down
Loading