Repository navigation
Expand file tree
/
Copy pathaction.yml
More file actions
217 lines (203 loc) · 11.1 KB
/
Copy pathaction.yml
File metadata and controls
217 lines (203 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
name: 'ESP Packaged Programmer'
description: 'Package esptool and the binaries into an executable'
inputs:
zipfile-id:
description: 'Artifact ID for the Zipfile to download. Zipfile should contain firmware.bin, bootloader.bin, partition-table.bin, and flasher_args.json. May optionally contain filesystem binaries and associated -flash_args files. NOTE: only one of zipfile-id or zipfile-name should be set. The structure of the zip should be the same as the build folder within the esp-idf build - so it should have the tree: build/, build/bootloader/, build/partition_table/'
required: false
default: ''
zipfile-name:
description: 'Name of the zipfile artifact that was packaged and uploaded. Zipfile should contain firmware.bin, bootloader.bin, partition-table.bin, and flasher_args.json. May optionally contain filesystem binaries and associated -flash_args files. NOTE: only one of zipfile-id or zipfile-name should be set. The structure of the zip should be the same as the build folder within the esp-idf build - so it should have the tree: build/, build/bootloader/, build/partition_table/'
required: false
default: ''
programmer-name:
description: 'Base name of the programmer executable. Will have version tag (e.g. v1.0.0 or commit hash if no tags) and OS suffix (e.g. windows, linux, macos) appended.'
required: false
default: 'programmer'
exclude-file-globs:
description: 'File globs to exclude from the build folder. This is a comma-separated list of filenames or globs. For example: "*.elf,*.pdb,app-flash_args". Defaults to "*.elf".'
required: false
default: '*.elf'
esptool-version:
description: 'Git tag of espressif/esptool to package, e.g. v4.7.0 or v5.6.0 (a leading "v" is added if missing). Use the version your build used: the flash arguments ESP-IDF generates into flasher_args.json / *-flash_args follow the tool (esptool 5 spells options with dashes, e.g. --flash-mode), so the packaged esptool must be the one they were written for; ESP-IDF 5.x builds with esptool 4.x, ESP-IDF 6.x with esptool 5.x. Leave it empty to take the version from a build/esptool_version.txt in the zipfile, which the build job writes with `python -m esptool version | tail -1 > build/esptool_version.txt` (see the README). With neither, v4.7.0 is packaged, with a warning.'
required: false
default: ''
python-version:
description: 'Python version to build the programmer with (actions/setup-python). esptool 4.x needs 3.7 or newer, esptool 5.x needs 3.10 or newer, so the default 3.10 serves both; raise it when a future esptool asks for more (pip refuses an esptool whose requires-python the chosen interpreter does not satisfy, and the build fails there, before packaging).'
required: false
default: '3.10'
outputs:
artifact-name:
description: "Name of the programmer artifact that was packaged and uploaded"
value: ${{ steps.output.outputs.artifact-name }}
runs:
using: "composite"
steps:
- name: Ensure that one of zipfile-id or zipfile-name is set
if: ${{ inputs.zipfile-id == '' && inputs.zipfile-name == '' }}
shell: bash
run: |
echo "::error title=⛔ error hint::Either zipfile-id or zipfile-name must be set"
exit 1
- name: Ensure that only zipfile-id or zipfile-name is set, not both
if: ${{ inputs.zipfile-id != '' && inputs.zipfile-name != '' }}
shell: bash
run: |
echo "::error title=⛔ error hint::Only one of zipfile-id or zipfile-name can be set"
exit 1
- name: Check Runner OS
if: ${{ runner.os != 'Linux' && runner.os != 'Windows' && runner.os != 'macOS'}}
shell: bash
run: |
echo "::error title=⛔ error hint::Support Linux, Windows, and macOS Only"
exit 1
- name: Clone the parent repo (to get the version)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get the version
shell: bash
run: |
echo "Trying to get the version from the parent repo"
# Get the version of the parent repo
version=$(git describe --tags --dirty || git rev-parse --short HEAD)
echo "Got version: ${version}"
# Set the version as an output variable
echo "version_str=$version" >> $GITHUB_ENV
- name: Setup XCode
if: ${{ runner.os == 'macOS' }}
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Set up Python
uses: actions/setup-python@v5
id: id_python_310
with:
python-version: ${{ inputs.python-version }}
- name: Download the zipfile artifact
uses: actions/download-artifact@v4
id: download_zipfile
with:
name: ${{ inputs.zipfile-name }}
artifact-ids: ${{ inputs.zipfile-id }}
path: ${{ github.action_path }}/build
# this is needed to ensure downloading by id doesn't add an additional
# folder
merge-multiple: true
- name: Remove any unneeded files from the build folder
shell: bash
if: ${{ inputs.exclude-file-globs != '' }}
working-directory: ${{ github.action_path }}
run: |
# for each of the file globs in the exclude-file-globs input, remove the
# files from the build folder
IFS=',' read -ra globs <<< "${{ inputs.exclude-file-globs }}"
for glob in "${globs[@]}"; do
# remove the leading and trailing spaces
glob=$(echo "$glob" | xargs)
echo "Cleaning up files matching pattern: $glob"
# remove the files from the build folder
find build -name "$glob" -exec rm -rf {} \;
done
- name: Resolve the esptool version to package
shell: bash
working-directory: ${{ github.action_path }}
env:
# through the environment, never interpolated into the script: the
# value comes from a caller's input or a build job's output
ESPTOOL_VERSION_INPUT: ${{ inputs.esptool-version }}
run: |
# the input, else build/esptool_version.txt from the zipfile (written by
# the build job from the esptool its ESP-IDF used), else v4.7.0
version="$(echo "$ESPTOOL_VERSION_INPUT" | xargs)"
if [ -n "$version" ]; then
echo "esptool version from the esptool-version input: $version"
elif [ -f build/esptool_version.txt ]; then
version="$(head -1 build/esptool_version.txt | xargs)"
echo "esptool version from build/esptool_version.txt in the zipfile: $version"
else
version="v4.7.0"
echo "::warning title=esptool version not given::Packaging esptool $version. Set the esptool-version input, or have the build job write the version it used to build/esptool_version.txt, so the packaged esptool matches the flash arguments ESP-IDF generated (see the README)."
fi
case "$version" in v*) ;; *) version="v$version" ;; esac
# a git tag of esptool's and nothing else (v4.7.0, v5.3.dev3 ...): the
# value reaches git and pip as an argument, and it came from a file in
# an artifact or a caller's input
tag_pattern='^v[0-9]+(\.[0-9A-Za-z]+)*$'
if ! [[ "$version" =~ $tag_pattern ]]; then
echo "::error title=⛔ error hint::esptool version '$version' is not a release tag like v4.7.0 or v5.6.0"
exit 1
fi
echo "Packaging esptool $version"
echo "esptool_version=$version" >> "$GITHUB_ENV"
# Build if windows
- name: PyInstaller
if: ${{ runner.os == 'Windows'}}
working-directory: ${{ github.action_path }}
shell: pwsh
run: |
# a failed native command does not stop a PowerShell script by itself
function Check($what) {
if ($LASTEXITCODE -ne 0) { Write-Error "$what failed with exit code $LASTEXITCODE"; exit 1 }
}
# setup the python environment (pyinstaller and esptool's dependencies)
${{ steps.id_python_310.outputs.python-path }} -m pip install -r requirements.txt
Check "pip install -r requirements.txt"
# clone esptool at the requested tag (resolved and validated by the
# step above, read from the environment at runtime) and install THAT:
# the packaged esptool (and its flasher-stub data, collected by
# programmer.spec from the installed package) is then exactly the
# version the caller built with
git clone --depth 1 --branch $env:esptool_version https://github.com/espressif/esptool
Check "git clone esptool $env:esptool_version"
${{ steps.id_python_310.outputs.python-path }} -m pip install ./esptool
Check "pip install ./esptool"
${{ steps.id_python_310.outputs.python-path }} -m esptool version
Check "esptool version"
# now build the installer
${{ steps.id_python_310.outputs.python-path }} -m PyInstaller --clean programmer.spec
Check "PyInstaller"
# now actually make the artifact
$artifact_name="${{ inputs.programmer-name }}_${{ env.version_str }}_windows.exe"
mv dist/programmer.exe ${artifact_name}
"artifactName=${artifact_name}" | Out-File -FilePath $env:GITHUB_ENV -Append
# Build if Linux or macOS
- name: PyInstaller
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
working-directory: ${{ github.action_path }}
shell: bash
run: |
set -euo pipefail
# save the runner OS to a variable in lower case
os_name=$(echo ${{ runner.os }} | tr '[:upper:]' '[:lower:]')
# setup the python environment (pyinstaller and esptool's dependencies)
${{ steps.id_python_310.outputs.python-path }} -m pip install -r requirements.txt
# clone esptool at the requested tag (resolved and validated by the
# step above, read from the environment at runtime) and install THAT:
# the packaged esptool (and its flasher-stub data, collected by
# programmer.spec from the installed package) is then exactly the
# version the caller built with
git clone --depth 1 --branch "$esptool_version" https://github.com/espressif/esptool
${{ steps.id_python_310.outputs.python-path }} -m pip install ./esptool
${{ steps.id_python_310.outputs.python-path }} -m esptool version
# now build the installer
${{ steps.id_python_310.outputs.python-path }} -m PyInstaller --clean programmer.spec
# now actually make the artifact
artifact_name="${{ inputs.programmer-name }}_${{ env.version_str }}_${os_name}.bin"
mv dist/programmer $artifact_name
echo "artifactName=$artifact_name" >> "$GITHUB_ENV"
# Set the ouput
- name: Set the action output
id: output
shell: bash
run: echo "artifact-name=${{ env.artifactName }}" >> $GITHUB_OUTPUT
# now actually upload the artifacts
- uses: actions/upload-artifact@v4
with:
name: ${{ env.artifactName }}
path: ${{ github.action_path }}/${{ env.artifactName }}
# attach the files to the release (if there is one)
- name: Attach files to release
uses: softprops/action-gh-release@v2
if: ${{ github.event.release && github.event.action == 'published' }}
with:
files: ${{ github.action_path }}/${{ env.artifactName }}