Release packaging: archives, workflow, download-first docs, Windows notes
release / release (push) Waiting to run
release / release (push) Waiting to run
- tools/build_release.sh: builds the Linux tar.gz and Windows zip from a git ref (default HEAD) using an explicit `git archive` pathspec allowlist: decoder (__init__.py, pd.py, gsmtap_stream.py), setup/start scripts, tools/vs_reader.py, READMEs, LICENSE and the README-referenced resources/ images. v* tags must match pd.py VERSION. Both archives are listed and extracted and checked for VERSION, py_compile, bash -n, .bat CRLF / .sh LF and tar exec bits; SHA256SUMS uses sha256sum or shasum. Builds into a staging dir and only then replaces dist/. - .github/workflows/release.yml: on a v* tag push run the unit tests, verify tag == pd.py VERSION, build, then upload into an existing release or create a draft and publish it; release-<tag> concurrency. - README/RUS: Installation documents both ways (release download recommended; source checkout for development), SHA256SUMS verification, and the Windows prerequisites verified against sigrok.org (0.7.2 release installer as the tested version, nightly caveat, VC++ 2010 redist, bundled fx2lafw firmware and Zadig, per-port driver binding). - start.bat: accept --opt=value alongside the original --opt value form (the usage text advertised the = form while the parser required a space); usage corrected and notes the core subset. - .gitignore: dist/. - AGENTS: release packaging, build verification and release process (commit docs/workflow first, then tag and push, auto-generated notes). No decoder behavior change; VERSION stays 1.9.7.
This commit is contained in:
1 parent
6e6f465841
commit
1cbafe715c
7 files changed
+518
-39
No files matched your search
@@ -0,0 +1,63 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref_name }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Unit tests
|
||||
run: python3 tests/test_gsmtap.py
|
||||
|
||||
- name: Verify tag matches pd.py VERSION
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version=$(sed -n "s/^VERSION = '\([0-9][0-9.]*\)'.*/\1/p" pd.py)
|
||||
if [ -z "$version" ]; then
|
||||
echo "::error::cannot read VERSION from pd.py"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$GITHUB_REF_NAME" != "v$version" ]; then
|
||||
echo "::error::tag $GITHUB_REF_NAME does not match pd.py VERSION '$version'"
|
||||
exit 1
|
||||
fi
|
||||
echo "tag $GITHUB_REF_NAME matches pd.py VERSION $version"
|
||||
|
||||
- name: Build release archives
|
||||
run: ./tools/build_release.sh "$GITHUB_REF_NAME"
|
||||
|
||||
- name: Create or update the GitHub release
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version=$(sed -n "s/^VERSION = '\([0-9][0-9.]*\)'.*/\1/p" pd.py)
|
||||
# Upload into an existing release first. If the release does not
|
||||
# exist yet, create it as a draft so the published release never
|
||||
# appears with a partial asset set.
|
||||
if ! gh release upload "$GITHUB_REF_NAME" dist/* --clobber; then
|
||||
gh release create "$GITHUB_REF_NAME" dist/* --draft \
|
||||
--title "sigrok_iso7816_stream $version" --generate-notes
|
||||
fi
|
||||
# Publish a new draft and re-publish an existing one.
|
||||
gh release edit "$GITHUB_REF_NAME" --draft=false
|
||||
@@ -4,3 +4,6 @@ __pycache__/
|
||||
|
||||
# Trace fixtures are local-only (large, machine-specific); never tracked.
|
||||
examples/
|
||||
|
||||
# Release archives built by tools/build_release.sh.
|
||||
dist/
|
||||
@@ -1019,6 +1019,44 @@ append the measured CLK frequency when known
|
||||
The decoder version is defined in `pd.py` as `VERSION = '1.9.7'`.
|
||||
The version is printed to the log on decoder startup.
|
||||
|
||||
### Release packaging (v1.9.7)
|
||||
|
||||
The GitHub release archives let users run the decoder without cloning the
|
||||
repo. `./tools/build_release.sh [REF]` (REF defaults to `HEAD`) builds
|
||||
`dist/sigrok_iso7816_stream-<VERSION>.tar.gz` (Linux) and
|
||||
`dist/sigrok_iso7816_stream-<VERSION>.zip` (Windows) plus
|
||||
`dist/SHA256SUMS`. `VERSION` comes from the ref's `pd.py`; a `v*` REF must
|
||||
equal it.
|
||||
|
||||
The release file set is an explicit allowlist passed to `git archive` as its
|
||||
pathspec, and also compared exactly against both archive listings (missing
|
||||
*and* unexpected entries fail): the decoder (`__init__.py`, `pd.py`,
|
||||
`gsmtap_stream.py`), the scripts (`setup.sh`/`start.sh`,
|
||||
`setup.bat`/`start.bat`), `tools/vs_reader.py`, `README.md`, `README_RUS.md`,
|
||||
`LICENSE`, and every `resources/` image referenced from `README.md`. Tests,
|
||||
`AGENTS.md`, the CI config, the development tools and the unreferenced
|
||||
`resources/` images never enter the release. No `export-ignore` rules are
|
||||
used, so GitHub's own source archives still contain the full tree. `dist/`
|
||||
is gitignored.
|
||||
|
||||
Both archives are unpacked and verified: `pd.py` VERSION, `py_compile` of the
|
||||
three modules, `bash -n` of the shell scripts, the tar exec bits, CRLF on the
|
||||
`.bat` files and no CR in the `.sh` files. The archives are built in a temp
|
||||
staging dir; only after every check passes are stale `dist/` archives removed
|
||||
and the new tar.gz/zip/`SHA256SUMS` moved in (a failed build leaves `dist/`
|
||||
untouched, and `gh release upload dist/*` can never attach a stale version).
|
||||
|
||||
`.github/workflows/release.yml` runs on a `v*` tag push: unit tests
|
||||
(`tests/test_gsmtap.py`), tag == `pd.py` VERSION, the build script, then
|
||||
`gh release upload --clobber` (or `gh release create --draft` when there is
|
||||
no release yet) followed by `gh release edit --draft=false`, with
|
||||
`release-<tag>` concurrency. **Release process:** commit the docs, workflow
|
||||
and scripts first, then tag `v1.9.7` and push the tag (with user approval) -
|
||||
the workflow must exist in the tagged commit, and the archive ships the
|
||||
committed READMEs. Release notes are GitHub's auto-generated notes from the
|
||||
commits; `AGENTS.md` and `tests/` are not in the archive. Packaging/docs
|
||||
only - no decoder behavior change, and `VERSION` is unchanged.
|
||||
|
||||
### Testing after decoder changes
|
||||
|
||||
After any change to `pd.py`:
|
||||
|
||||
@@ -117,13 +117,17 @@ data flags and are not part of the libosmocore spec.
|
||||
|
||||
## Usage
|
||||
|
||||
Quick start after cloning (see Installation below):
|
||||
Quick start (after installing — release download or source checkout; see
|
||||
Installation below):
|
||||
|
||||
```bash
|
||||
./setup.sh # check sigrok-cli, register decoder symlink
|
||||
./start.sh # capture + GSMTAP stream to 127.0.0.1:4729
|
||||
```
|
||||
|
||||
On Windows the same two steps are `setup.bat` then `start.bat` (see
|
||||
Installation below).
|
||||
|
||||
`start.sh` defaults: pins D5=CLK, D0=I/O, D4=RST, D2=VCC, 16 MHz samplerate.
|
||||
Override via args:
|
||||
|
||||
@@ -318,27 +322,61 @@ same restriction.
|
||||
|
||||
## Installation
|
||||
|
||||
### Linux
|
||||
Both ways install the same decoder — pick one:
|
||||
|
||||
- **Download (recommended)** — a release archive. Nothing to clone and no git
|
||||
history: extract it, run `setup`, run `start`. Best if you only want to
|
||||
capture.
|
||||
- **Source checkout** — a `git clone`. The same runtime plus the development
|
||||
material: `tests/` and the trace/baseline tools (`tools/capture_baseline.sh`,
|
||||
`tools/compare_baseline.sh`, `tools/vs_reader.py`). The example traces
|
||||
(`examples/`) are gitignored and stay local in either case. The release
|
||||
archives intentionally do not contain `tests/`, the dev tools or
|
||||
`examples/`.
|
||||
|
||||
### Download (recommended)
|
||||
|
||||
Grab the latest archive from
|
||||
[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest):
|
||||
|
||||
- `sigrok_iso7816_stream-<version>.tar.gz` — Linux
|
||||
- `sigrok_iso7816_stream-<version>.zip` — Windows
|
||||
|
||||
Each release also publishes `SHA256SUMS`, which lists **both** archives; keep
|
||||
it next to the file you downloaded and verify:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
cd sigrok_iso7816_stream
|
||||
sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux)
|
||||
```
|
||||
|
||||
On Windows run `certutil -hashfile sigrok_iso7816_stream-<version>.zip SHA256`
|
||||
and compare the output with the `.zip` line in `SHA256SUMS`.
|
||||
|
||||
#### Linux (download)
|
||||
|
||||
```bash
|
||||
tar xzf sigrok_iso7816_stream-<version>.tar.gz
|
||||
cd sigrok_iso7816_stream-<version>
|
||||
./setup.sh
|
||||
./start.sh
|
||||
```
|
||||
|
||||
`setup.sh` verifies sigrok-cli and the FX2 firmware package
|
||||
(`sigrok-firmware-fx2lafw`) are installed, symlinks the repo into
|
||||
(`sigrok-firmware-fx2lafw`) are installed, symlinks the project directory into
|
||||
`~/.local/share/libsigrokdecode/decoders/iso7816` (user-local decoders shadow
|
||||
system-wide ones), and probes the connected device for its maximum supported
|
||||
samplerate.
|
||||
|
||||
### Windows
|
||||
#### Windows (download)
|
||||
|
||||
Prerequisites:
|
||||
|
||||
1. **sigrok-cli** Windows installer (0.7.2 x86_64) from
|
||||
[sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads).
|
||||
If it fails to start with error `0xc0150002`, install the
|
||||
[sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) — the tested
|
||||
release. Nightly Windows installers are also published on that page; they
|
||||
may change the sigrok-cli syntax or the decoder API, so the 0.7.2
|
||||
release installer remains the supported version.
|
||||
If sigrok-cli fails to start with error `0xc0150002`, install the
|
||||
[Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999)
|
||||
(`msvcr100.dll` is required by the bundled Python runtime).
|
||||
2. fx2lafw firmware ships bundled with the installer — no separate download.
|
||||
@@ -354,7 +392,40 @@ Driver setup (FX2 dongles need WinUSB, the vendor driver won't work):
|
||||
- Windows binds drivers per USB port when no serial number is present:
|
||||
moving the dongle to another port may require repeating Zadig.
|
||||
|
||||
Then:
|
||||
Then extract the release `.zip` (right-click → Extract All in Explorer) and
|
||||
run, inside the extracted folder:
|
||||
|
||||
```bat
|
||||
setup.bat
|
||||
start.bat
|
||||
```
|
||||
|
||||
`setup.bat` verifies sigrok-cli and bundled firmware, registers this project's
|
||||
decoder via a junction into `%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816`
|
||||
(confirmed by `sigrok-cli -L` listing `iso7816`), and probes the device's
|
||||
accepted samplerates. The release zip ships the batch files with CRLF line
|
||||
endings, so no conversion is needed. `start.bat --help` lists its options
|
||||
(the core subset of `start.sh`: channels, samplerate, clock, host/port, pcap,
|
||||
protocol, debug).
|
||||
|
||||
### Linux (source checkout)
|
||||
|
||||
```bash
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
cd sigrok_iso7816_stream
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
A fresh clone needs the same `./setup.sh` checks and symlink as above: it
|
||||
verifies sigrok-cli and the FX2 firmware package, symlinks the project
|
||||
directory into `~/.local/share/libsigrokdecode/decoders/iso7816` and probes
|
||||
the device's maximum samplerate.
|
||||
|
||||
### Windows (source checkout)
|
||||
|
||||
The Windows prerequisites (sigrok-cli + the Visual C++ 2010 Redistributable,
|
||||
the bundled fx2lafw firmware, and the Zadig/WinUSB driver setup) are the same
|
||||
as in [Windows (download)](#windows-download) above.
|
||||
|
||||
```bat
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
@@ -362,10 +433,15 @@ cd sigrok_iso7816_stream
|
||||
setup.bat
|
||||
```
|
||||
|
||||
`setup.bat` verifies sigrok-cli and bundled firmware, registers this repo's
|
||||
decoder via a junction into `%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816`
|
||||
(confirmed by `sigrok-cli -L` listing `iso7816`), and probes the device's
|
||||
accepted samplerates.
|
||||
`setup.bat` performs the same checks and junction registration as above.
|
||||
`start.bat` supports the core option subset (channels, samplerate, clock,
|
||||
host/port, pcap, protocol, debug; `start.sh` has the full set) — the space
|
||||
form is the primary one, and `--clk=CH` also works:
|
||||
|
||||
```bat
|
||||
start.bat --clk D1 --data D6
|
||||
start.bat --help
|
||||
```
|
||||
|
||||
Capture works the same as on Linux:
|
||||
|
||||
@@ -374,7 +450,8 @@ start.bat rem capture + GSMTAP stream
|
||||
```
|
||||
|
||||
Note: batch files need CRLF line endings; the repo enforces this via
|
||||
`.gitattributes`, so a fresh clone on Windows is already correct.
|
||||
`.gitattributes`, so a fresh clone on Windows is already correct (the release
|
||||
zip ships the same CRLF files).
|
||||
|
||||
## RST/VCC detection notes and limitations
|
||||
|
||||
|
||||
+92
-15
@@ -121,13 +121,17 @@ flags) USB-протокола simtrace2 и не является частью с
|
||||
|
||||
## Использование
|
||||
|
||||
Быстрый старт после клонирования (см. «Установка» ниже):
|
||||
Быстрый старт (после установки — скачанный архив или клон репозитория;
|
||||
см. «Установка» ниже):
|
||||
|
||||
```bash
|
||||
./setup.sh # проверить sigrok-cli, зарегистрировать симлинк декодера
|
||||
./start.sh # запись + поток GSMTAP на 127.0.0.1:4729
|
||||
```
|
||||
|
||||
В Windows те же два шага — `setup.bat`, затем `start.bat` (см. «Установка»
|
||||
ниже).
|
||||
|
||||
Умолчания `start.sh`: выводы D5=CLK, D0=I/O, D4=RST, D2=VCC, частота
|
||||
дискретизации 16 МГц. Переопределяются аргументами:
|
||||
|
||||
@@ -331,27 +335,60 @@ libsigrok ограничивает 12 МГц. Поэтому `start.sh`/`start.
|
||||
|
||||
## Установка
|
||||
|
||||
### Linux
|
||||
Оба способа ставят один и тот же декодер — выберите один:
|
||||
|
||||
- **Скачать (рекомендуется)** — архив релиза. Не нужно ничего клонировать и
|
||||
нет истории git: распакуйте, запустите `setup`, затем `start`. Лучший
|
||||
вариант, если нужен только съём.
|
||||
- **Из исходников** — `git clone`. Тот же рантайм плюс материал для
|
||||
разработки: `tests/` и инструменты трасс и базовой линии
|
||||
(`tools/capture_baseline.sh`, `tools/compare_baseline.sh`,
|
||||
`tools/vs_reader.py`). Трассы примеров (`examples/`) исключены из git и в
|
||||
любом случае остаются локальными. В архивах релиза намеренно нет `tests/`,
|
||||
dev-инструментов и `examples/`.
|
||||
|
||||
### Скачать (рекомендуется)
|
||||
|
||||
Скачайте последний архив со страницы
|
||||
[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest):
|
||||
|
||||
- `sigrok_iso7816_stream-<version>.tar.gz` — Linux
|
||||
- `sigrok_iso7816_stream-<version>.zip` — Windows
|
||||
|
||||
К каждому релизу прилагается `SHA256SUMS` — в нём **оба** архива.
|
||||
Положите файл рядом со скачанным архивом и проверьте:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
cd sigrok_iso7816_stream
|
||||
sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux)
|
||||
```
|
||||
|
||||
В Windows выполните `certutil -hashfile sigrok_iso7816_stream-<version>.zip SHA256`
|
||||
и сравните вывод со строкой `.zip` в `SHA256SUMS`.
|
||||
|
||||
#### Linux (скачать)
|
||||
|
||||
```bash
|
||||
tar xzf sigrok_iso7816_stream-<version>.tar.gz
|
||||
cd sigrok_iso7816_stream-<version>
|
||||
./setup.sh
|
||||
./start.sh
|
||||
```
|
||||
|
||||
`setup.sh` проверяет, что установлены sigrok-cli и пакет прошивки FX2
|
||||
(`sigrok-firmware-fx2lafw`), создаёт симлинк репозитория в
|
||||
(`sigrok-firmware-fx2lafw`), создаёт симлинк каталога проекта в
|
||||
`~/.local/share/libsigrokdecode/decoders/iso7816` (пользовательские
|
||||
декодеры перекрывают системные) и опрашивает подключённое устройство на
|
||||
предмет максимальной поддерживаемой частоты дискретизации.
|
||||
|
||||
### Windows
|
||||
#### Windows (скачать)
|
||||
|
||||
Предварительные требования:
|
||||
|
||||
1. **sigrok-cli** — установщик для Windows (0.7.2 x86_64) с
|
||||
[sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads).
|
||||
Если он не запускается с ошибкой `0xc0150002`, установите
|
||||
[sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) —
|
||||
протестированная версия. На этой же странице публикуются ночные сборки
|
||||
для Windows; они могут менять синтаксис sigrok-cli или API декодеров,
|
||||
поэтому поддерживаемой остаётся версия из релизного установщика 0.7.2. Если sigrok-cli не запускается с ошибкой `0xc0150002`, установите
|
||||
[Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999)
|
||||
(`msvcr100.dll` требуется встроенному Python-рантайму).
|
||||
2. Прошивка fx2lafw поставляется вместе с установщиком — отдельно скачивать не нужно.
|
||||
@@ -367,7 +404,42 @@ cd sigrok_iso7816_stream
|
||||
- Windows привязывает драйверы к USB-порту, когда нет серийного номера:
|
||||
перенос донгла в другой порт может потребовать повторить Zadig.
|
||||
|
||||
Затем:
|
||||
Затем распакуйте архив `.zip` (в Проводнике: правой кнопкой → «Извлечь все»)
|
||||
и запустите в распакованном каталоге:
|
||||
|
||||
```bat
|
||||
setup.bat
|
||||
start.bat
|
||||
```
|
||||
|
||||
`setup.bat` проверяет sigrok-cli и встроенную прошивку, регистрирует декодер
|
||||
этого проекта через junction в
|
||||
`%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` (подтверждается тем, что
|
||||
`sigrok-cli -L` показывает `iso7816`), и опрашивает устройство на предмет
|
||||
поддерживаемых частот дискретизации. В zip-архиве релиза bat-файлы уже с
|
||||
переводами строк CRLF, поэтому преобразование не требуется.
|
||||
`start.bat --help` перечисляет его опции (основное подмножество `start.sh`:
|
||||
каналы, частота дискретизации, clock, host/port, pcap, protocol, debug).
|
||||
|
||||
### Linux (из исходников)
|
||||
|
||||
```bash
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
cd sigrok_iso7816_stream
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
Свежему клону нужны те же проверки и симлинк `./setup.sh`, что и выше: он
|
||||
проверяет sigrok-cli и пакет прошивки FX2, создаёт симлинк каталога проекта
|
||||
в `~/.local/share/libsigrokdecode/decoders/iso7816` и опрашивает устройство
|
||||
на предмет максимальной частоты дискретизации.
|
||||
|
||||
### Windows (из исходников)
|
||||
|
||||
Предварительные требования Windows (sigrok-cli и Visual C++ 2010
|
||||
Redistributable, встроенная прошивка fx2lafw и настройка драйвера
|
||||
Zadig/WinUSB) — те же, что в разделе
|
||||
[Windows (скачать)](#windows-скачать) выше.
|
||||
|
||||
```bat
|
||||
git clone git@github.com:anttro/sigrok_iso7816_stream.git
|
||||
@@ -375,11 +447,15 @@ cd sigrok_iso7816_stream
|
||||
setup.bat
|
||||
```
|
||||
|
||||
`setup.bat` проверяет sigrok-cli и встроенную прошивку, регистрирует декодер
|
||||
этого репозитория через junction в
|
||||
`%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` (подтверждается тем, что
|
||||
`sigrok-cli -L` показывает `iso7816`), и опрашивает устройство на предмет
|
||||
поддерживаемых частот дискретизации.
|
||||
`setup.bat` выполняет те же проверки и регистрацию junction, что и выше.
|
||||
`start.bat` поддерживает основное подмножество опций (каналы, частота
|
||||
дискретизации, clock, host/port, pcap, protocol, debug; полный набор — в
|
||||
`start.sh`) — основной формат с пробелом, а `--clk=CH` тоже работает:
|
||||
|
||||
```bat
|
||||
start.bat --clk D1 --data D6
|
||||
start.bat --help
|
||||
```
|
||||
|
||||
Запись работает так же, как в Linux:
|
||||
|
||||
@@ -388,7 +464,8 @@ start.bat rem запись + поток GSMTAP
|
||||
```
|
||||
|
||||
Примечание: bat-файлы требуют переводов строк CRLF; репозиторий следит за
|
||||
этим через `.gitattributes`, поэтому свежий клон в Windows уже корректен.
|
||||
этим через `.gitattributes`, поэтому свежий клон в Windows уже корректен
|
||||
(zip-архив релиза содержит те же файлы с CRLF).
|
||||
|
||||
## Заметки и ограничения по детектированию RST/VCC
|
||||
|
||||
|
||||
@@ -36,27 +36,43 @@ if /i "%~1"=="--no-rst" ( set "RST=" & shift & goto :argloop )
|
||||
if /i "%~1"=="--no-vcc" ( set "VCC=" & shift & goto :argloop )
|
||||
if /i "%~1"=="-h" ( goto :usage )
|
||||
if /i "%~1"=="--help" ( goto :usage )
|
||||
rem Value options also accept the --opt=value form (usage shows the space form).
|
||||
for /f "tokens=1,* delims==" %%A in ("%~1") do (
|
||||
if /i "%%A"=="--clk" ( set "CLK=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--data" ( set "DATA=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--rst" ( set "RST=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--vcc" ( set "VCC=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--samplerate" ( set "SAMPLERATE=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--clock" ( set "CLOCK=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--host" ( set "HOST=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--port" ( set "PORT=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--pcap" ( set "PCAP=%%B" & shift & goto :argloop )
|
||||
if /i "%%A"=="--protocol" ( set "PROTOCOL=%%B" & shift & goto :argloop )
|
||||
)
|
||||
echo Unknown option: %~1
|
||||
exit /b 1
|
||||
|
||||
:usage
|
||||
echo Usage: %~n0 [OPTIONS]
|
||||
echo --clk=CH CLK channel default: %CLK%
|
||||
echo --data=CH I/O channel default: %DATA%
|
||||
echo --rst=CH RST channel default: %RST%
|
||||
echo --vcc=CH VCC channel default: %VCC%
|
||||
echo --samplerate=SR Sample rate default: %SAMPLERATE%
|
||||
echo --clock=MODE native/detect/sample_as_clock
|
||||
echo --host=IP GSMTAP destination default: 127.0.0.1
|
||||
echo --port=N GSMTAP port default: 4729
|
||||
echo --pcap=FILE Also write decoded events to FILE (no spaces in path)
|
||||
echo --clk CH CLK channel default: %CLK%
|
||||
echo --data CH I/O channel default: %DATA%
|
||||
echo --rst CH RST channel default: %RST%
|
||||
echo --vcc CH VCC channel default: %VCC%
|
||||
echo --samplerate SR Sample rate default: %SAMPLERATE%
|
||||
echo --clock MODE native/detect/sample_as_clock
|
||||
echo --host IP GSMTAP destination default: 127.0.0.1
|
||||
echo --port N GSMTAP port default: 4729
|
||||
echo --pcap FILE Also write decoded events to FILE (no spaces in path)
|
||||
echo --debug Full decoder + sigrok output (all annotation rows + -l 4).
|
||||
echo
|
||||
echo By default only decoded APDUs and decoder warnings/errors are shown.
|
||||
echo --protocol=MODE T=0 (default), T=1, or auto (mid-session decode)
|
||||
echo --protocol MODE T=0 (default), T=1, or auto (mid-session decode)
|
||||
echo --no-rst Disable RST tracking
|
||||
echo --no-vcc Disable VCC tracking
|
||||
echo.
|
||||
echo The --clk=CH form also works. start.bat supports this core subset;
|
||||
echo start.sh has the full option set.
|
||||
echo.
|
||||
echo To log output on Windows use redirection: %~n0 ... ^> capture.log 2^>^&1
|
||||
exit /b 0
|
||||
|
||||
|
||||
Executable
+205
@@ -0,0 +1,205 @@
|
||||
#!/bin/bash
|
||||
# Build the GitHub release archives from a git ref.
|
||||
# Usage: ./tools/build_release.sh [REF]
|
||||
#
|
||||
# REF defaults to HEAD. The archives carry an explicit path allowlist: the
|
||||
# decoder, the setup/start scripts, tools/vs_reader.py, the two READMEs, the
|
||||
# license and the images the READMEs reference. The allowlist is passed to
|
||||
# `git archive` as its pathspec, so tests/, AGENTS.md, the CI config and the
|
||||
# development tools never enter the release — and the repository's own
|
||||
# (auto-generated) source archives are not affected.
|
||||
#
|
||||
# A v* tag must match the VERSION line in that ref's pd.py.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
die() { echo "build_release: $*" >&2; exit 1; }
|
||||
|
||||
REF="${1:-HEAD}"
|
||||
git rev-parse --verify "$REF^{commit}" >/dev/null 2>&1 || die "unknown ref: $REF"
|
||||
|
||||
VERSION="$(git show "$REF:pd.py" | sed -n "s/^VERSION = '\([0-9][0-9.]*\)'.*/\1/p")"
|
||||
[ -n "$VERSION" ] || die "cannot read VERSION from $REF:pd.py"
|
||||
|
||||
case "$REF" in
|
||||
v*)
|
||||
[ "${REF#v}" = "$VERSION" ] || \
|
||||
die "tag $REF does not match pd.py VERSION '$VERSION'"
|
||||
;;
|
||||
esac
|
||||
|
||||
PREFIX="sigrok_iso7816_stream-${VERSION}"
|
||||
|
||||
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/sigrok_release.XXXXXX")"
|
||||
trap 'rm -rf "$STAGE"' EXIT
|
||||
|
||||
# --- expected release contents (allowlist) -------------------------------
|
||||
# The base runtime files plus every image referenced from the READMEs.
|
||||
README_RES="$(git show "$REF:README.md" \
|
||||
| grep -oE '\]\(resources/[^)]+' | sed 's/](//' | LC_ALL=C sort -u || true)"
|
||||
[ -n "$README_RES" ] || die "no resources/ images referenced from $REF:README.md"
|
||||
README_RUS_RES="$(git show "$REF:README_RUS.md" \
|
||||
| grep -oE '\]\(resources/[^)]+' | sed 's/](//' | LC_ALL=C sort -u || true)"
|
||||
[ "$README_RES" = "$README_RUS_RES" ] || \
|
||||
die "README.md and README_RUS.md reference different resources/ images"
|
||||
|
||||
EXPECTED="$STAGE/expected.list"
|
||||
{
|
||||
printf '%s\n' \
|
||||
__init__.py pd.py gsmtap_stream.py \
|
||||
setup.sh start.sh setup.bat start.bat \
|
||||
tools/vs_reader.py README.md README_RUS.md LICENSE
|
||||
printf '%s\n' "$README_RES"
|
||||
} | LC_ALL=C sort -u > "$EXPECTED"
|
||||
|
||||
PATHS=()
|
||||
while IFS= read -r path; do
|
||||
PATHS+=("$path")
|
||||
done < "$EXPECTED"
|
||||
|
||||
# Build into the staging directory; dist/ is only touched after every check
|
||||
# passes, so a failed build never leaves unverified archives behind.
|
||||
git archive --format=tar.gz --prefix="${PREFIX}/" "$REF" \
|
||||
-o "$STAGE/${PREFIX}.tar.gz" -- "${PATHS[@]}"
|
||||
git archive --format=zip --prefix="${PREFIX}/" "$REF" \
|
||||
-o "$STAGE/${PREFIX}.zip" -- "${PATHS[@]}"
|
||||
|
||||
# --- archive listings ----------------------------------------------------
|
||||
list_archive() {
|
||||
case "$1" in
|
||||
*.zip)
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
unzip -Z1 "$1"
|
||||
else
|
||||
python3 - "$1" <<'PY'
|
||||
import sys, zipfile
|
||||
with zipfile.ZipFile(sys.argv[1]) as z:
|
||||
for name in z.namelist():
|
||||
print(name)
|
||||
PY
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
tar tzf "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
normalize_listing() {
|
||||
# Strip the top-level prefix, drop directory entries, sort.
|
||||
awk -v p="$PREFIX/" '
|
||||
index($0, p) == 1 {
|
||||
name = substr($0, length(p) + 1)
|
||||
if (name != "" && name !~ /\/$/) print name
|
||||
}' | LC_ALL=C sort
|
||||
}
|
||||
|
||||
DEV_PATHS=(
|
||||
tests/
|
||||
AGENTS.md
|
||||
.github/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
examples/
|
||||
tools/build_release.sh
|
||||
tools/capture_baseline.sh
|
||||
tools/compare_baseline.sh
|
||||
tools/signal_diagnostic.py
|
||||
)
|
||||
|
||||
check_archive_listing() {
|
||||
local archive="$1" listing="$2" actual="$3" path
|
||||
# Defense in depth: the pathspec already excludes these, but a future
|
||||
# refactor must not silently ship them.
|
||||
for path in "${DEV_PATHS[@]}"; do
|
||||
if grep -qF "${PREFIX}/${path}" "$listing"; then
|
||||
die "$archive unexpectedly contains dev-only path ${path}"
|
||||
fi
|
||||
done
|
||||
normalize_listing < "$listing" > "$actual"
|
||||
if ! diff -u "$EXPECTED" "$actual" > "$STAGE/list.diff"; then
|
||||
cat "$STAGE/list.diff" >&2
|
||||
die "$archive contents do not match the release allowlist (expected vs actual above)"
|
||||
fi
|
||||
}
|
||||
|
||||
list_archive "$STAGE/${PREFIX}.tar.gz" > "$STAGE/tar.list"
|
||||
list_archive "$STAGE/${PREFIX}.zip" > "$STAGE/zip.list"
|
||||
check_archive_listing "$STAGE/${PREFIX}.tar.gz" "$STAGE/tar.list" "$STAGE/tar.files"
|
||||
check_archive_listing "$STAGE/${PREFIX}.zip" "$STAGE/zip.list" "$STAGE/zip.files"
|
||||
|
||||
# --- unpack and verify both archives -------------------------------------
|
||||
mkdir -p "$STAGE/tar" "$STAGE/zip"
|
||||
tar xzf "$STAGE/${PREFIX}.tar.gz" -C "$STAGE/tar"
|
||||
TAR_DIR="$STAGE/tar/$PREFIX"
|
||||
[ -f "$TAR_DIR/pd.py" ] || die "tar.gz did not unpack ${PREFIX}/pd.py"
|
||||
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
unzip -q "$STAGE/${PREFIX}.zip" -d "$STAGE/zip"
|
||||
else
|
||||
python3 - "$STAGE/${PREFIX}.zip" "$STAGE/zip" <<'PY'
|
||||
import sys, zipfile
|
||||
with zipfile.ZipFile(sys.argv[1]) as z:
|
||||
z.extractall(sys.argv[2])
|
||||
PY
|
||||
fi
|
||||
ZIP_DIR="$STAGE/zip/$PREFIX"
|
||||
[ -f "$ZIP_DIR/pd.py" ] || die "zip did not unpack ${PREFIX}/pd.py"
|
||||
|
||||
check_tree() {
|
||||
local src="$1" label="$2" file found
|
||||
found="$(sed -n "s/^VERSION = '\([0-9][0-9.]*\)'.*/\1/p" "$src/pd.py")"
|
||||
[ "$found" = "$VERSION" ] || \
|
||||
die "$label: pd.py VERSION '$found', expected '$VERSION'"
|
||||
python3 -m py_compile "$src/pd.py" "$src/gsmtap_stream.py" "$src/__init__.py" || \
|
||||
die "$label: py_compile failed"
|
||||
for file in setup.sh start.sh; do
|
||||
bash -n "$src/$file" || die "$label: bash -n $file failed"
|
||||
done
|
||||
for file in setup.bat start.bat; do
|
||||
python3 - "$src/$file" <<'PY' || die "$label: $file is not CRLF-terminated"
|
||||
import sys
|
||||
data = open(sys.argv[1], 'rb').read()
|
||||
if b'\n' not in data or data.count(b'\n') != data.count(b'\r\n'):
|
||||
sys.exit(1)
|
||||
PY
|
||||
done
|
||||
for file in setup.sh start.sh; do
|
||||
if grep -q $'\r' "$src/$file"; then
|
||||
die "$label: $file contains CR (expected LF only)"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_tree "$TAR_DIR" "tar.gz"
|
||||
check_tree "$ZIP_DIR" "zip"
|
||||
|
||||
[ -x "$TAR_DIR/setup.sh" ] || die "setup.sh is not executable in the tar.gz"
|
||||
[ -x "$TAR_DIR/start.sh" ] || die "start.sh is not executable in the tar.gz"
|
||||
|
||||
# --- checksums and publish ----------------------------------------------
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
SHA256=(sha256sum)
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
SHA256=(shasum -a 256)
|
||||
else
|
||||
die "neither sha256sum nor shasum is available"
|
||||
fi
|
||||
(cd "$STAGE" && "${SHA256[@]}" "${PREFIX}.tar.gz" "${PREFIX}.zip" > SHA256SUMS)
|
||||
|
||||
# Verified: replace any previous release files so a later `gh release upload
|
||||
# dist/*` can never attach a stale archive.
|
||||
mkdir -p dist
|
||||
rm -f dist/sigrok_iso7816_stream-*.tar.gz \
|
||||
dist/sigrok_iso7816_stream-*.zip \
|
||||
dist/SHA256SUMS
|
||||
mv "$STAGE/${PREFIX}.tar.gz" "$STAGE/${PREFIX}.zip" "$STAGE/SHA256SUMS" dist/
|
||||
|
||||
echo "Built release archives (VERSION $VERSION):"
|
||||
du -h "dist/${PREFIX}.tar.gz" "dist/${PREFIX}.zip"
|
||||
echo ""
|
||||
echo "dist/SHA256SUMS:"
|
||||
cat dist/SHA256SUMS
|
||||
Reference in new issue
Block a user