beqforge 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- beqforge-0.1.0/.github/dependabot.yml +10 -0
- beqforge-0.1.0/.github/workflows/build-device-check.yml +75 -0
- beqforge-0.1.0/.github/workflows/build-executable.yml +172 -0
- beqforge-0.1.0/.github/workflows/dependabot-auto-merge.yaml +23 -0
- beqforge-0.1.0/.github/workflows/tests.yml +101 -0
- beqforge-0.1.0/.gitignore +270 -0
- beqforge-0.1.0/.idea/.gitignore +10 -0
- beqforge-0.1.0/.idea/beqforge.iml +11 -0
- beqforge-0.1.0/.idea/editor.xml +276 -0
- beqforge-0.1.0/.idea/jsonSchemas.xml +25 -0
- beqforge-0.1.0/.idea/misc.xml +6 -0
- beqforge-0.1.0/.idea/modules.xml +8 -0
- beqforge-0.1.0/.idea/vcs.xml +6 -0
- beqforge-0.1.0/AGENTS.md +87 -0
- beqforge-0.1.0/CLAUDE.md +25 -0
- beqforge-0.1.0/LICENCE.md +21 -0
- beqforge-0.1.0/PKG-INFO +399 -0
- beqforge-0.1.0/README.md +373 -0
- beqforge-0.1.0/TODO.md +341 -0
- beqforge-0.1.0/beq_common/AGENTS.md +34 -0
- beqforge-0.1.0/beq_common/__init__.py +6 -0
- beqforge-0.1.0/beq_common/biquad.py +427 -0
- beqforge-0.1.0/beq_common/provenance.py +44 -0
- beqforge-0.1.0/beq_common/publication.py +20 -0
- beqforge-0.1.0/beq_common/types.py +30 -0
- beqforge-0.1.0/beqforge/AGENTS.md +530 -0
- beqforge-0.1.0/beqforge/__init__.py +79 -0
- beqforge-0.1.0/beqforge/accept.py +739 -0
- beqforge-0.1.0/beqforge/beqd.py +202 -0
- beqforge-0.1.0/beqforge/biquad.py +27 -0
- beqforge-0.1.0/beqforge/cache.py +616 -0
- beqforge-0.1.0/beqforge/charts.py +375 -0
- beqforge-0.1.0/beqforge/cli.py +61 -0
- beqforge-0.1.0/beqforge/design.py +394 -0
- beqforge-0.1.0/beqforge/designer.py +624 -0
- beqforge-0.1.0/beqforge/diagnose.py +763 -0
- beqforge-0.1.0/beqforge/explain.py +248 -0
- beqforge-0.1.0/beqforge/extraction.py +469 -0
- beqforge-0.1.0/beqforge/filters.py +1161 -0
- beqforge-0.1.0/beqforge/harness.py +457 -0
- beqforge-0.1.0/beqforge/identify.py +295 -0
- beqforge-0.1.0/beqforge/material.py +187 -0
- beqforge-0.1.0/beqforge/pipeline.py +1995 -0
- beqforge-0.1.0/beqforge/record.py +525 -0
- beqforge-0.1.0/beqforge/reference.py +153 -0
- beqforge-0.1.0/beqforge/rolloff.py +138 -0
- beqforge-0.1.0/beqforge/verify.py +486 -0
- beqforge-0.1.0/beqforge-device-check.spec +63 -0
- beqforge-0.1.0/beqforge.spec +77 -0
- beqforge-0.1.0/beqforge_device_check/AGENTS.md +68 -0
- beqforge-0.1.0/beqforge_device_check/__init__.py +3 -0
- beqforge-0.1.0/beqforge_device_check/analyse.py +788 -0
- beqforge-0.1.0/beqforge_device_check/audio.py +205 -0
- beqforge-0.1.0/beqforge_device_check/catalogue.py +359 -0
- beqforge-0.1.0/beqforge_device_check/cli.py +956 -0
- beqforge-0.1.0/beqforge_device_check/coefficients.py +100 -0
- beqforge-0.1.0/beqforge_device_check/engines.py +531 -0
- beqforge-0.1.0/beqforge_device_check/evidence.py +245 -0
- beqforge-0.1.0/beqforge_device_check/manifest.py +337 -0
- beqforge-0.1.0/beqforge_device_check/measurement.py +353 -0
- beqforge-0.1.0/beqforge_device_check/profiles.py +117 -0
- beqforge-0.1.0/beqforge_device_check/qualification.py +548 -0
- beqforge-0.1.0/beqforge_device_check/report.py +727 -0
- beqforge-0.1.0/beqforge_device_check/transactions.py +708 -0
- beqforge-0.1.0/beqforge_device_check/verify.py +250 -0
- beqforge-0.1.0/beqoptimiser/AGENTS.md +74 -0
- beqforge-0.1.0/beqoptimiser/__init__.py +34 -0
- beqforge-0.1.0/beqoptimiser/cache.py +358 -0
- beqforge-0.1.0/beqoptimiser/cli.py +184 -0
- beqforge-0.1.0/beqoptimiser/core.py +356 -0
- beqforge-0.1.0/beqoptimiser/data/seed-manifest.json +40 -0
- beqforge-0.1.0/beqoptimiser/data/seed.json.gz +0 -0
- beqforge-0.1.0/docs/device-check-examples/minidsp-2x4hd-usb-loopback.json +317 -0
- beqforge-0.1.0/docs/device-check-examples/simulation.json +32 -0
- beqforge-0.1.0/docs/device-check.md +360 -0
- beqforge-0.1.0/docs/optimiser-report/README.md +92 -0
- beqforge-0.1.0/docs/optimiser-report/assets/aggregate-48000.png +0 -0
- beqforge-0.1.0/docs/optimiser-report/assets/aggregate-96000.png +0 -0
- beqforge-0.1.0/docs/optimiser-report/assets/example-1.png +0 -0
- beqforge-0.1.0/docs/optimiser-report/assets/example-2.png +0 -0
- beqforge-0.1.0/docs/optimiser-report/entry-results.json.gz +0 -0
- beqforge-0.1.0/docs/optimiser-report/statistics.json +17762 -0
- beqforge-0.1.0/docs/optimiser.md +168 -0
- beqforge-0.1.0/evidence_validation.json +395 -0
- beqforge-0.1.0/negative_corpus.json +1450 -0
- beqforge-0.1.0/packaging/device-check/NOTICE.txt +16 -0
- beqforge-0.1.0/plans/F2-catalogue-filter-optimisation.md +448 -0
- beqforge-0.1.0/plans/F2-device-precision-validation.md +904 -0
- beqforge-0.1.0/plans/F2-package-consolidation.md +94 -0
- beqforge-0.1.0/plans/R2a-server-stage-cache.md +208 -0
- beqforge-0.1.0/plans/done-baseline-evidence.md +89 -0
- beqforge-0.1.0/plans/done-design-and-pipeline.md +868 -0
- beqforge-0.1.0/plans/research-design-decisions.md +403 -0
- beqforge-0.1.0/plans/test-portability-and-runtime.md +68 -0
- beqforge-0.1.0/pyproject.toml +52 -0
- beqforge-0.1.0/tests/__init__.py +1 -0
- beqforge-0.1.0/tests/conftest.py +14 -0
- beqforge-0.1.0/tests/fixtures/optimiser_seed_entry.json +204 -0
- beqforge-0.1.0/tests/test_cli.py +37 -0
- beqforge-0.1.0/tests/test_design_accept.py +645 -0
- beqforge-0.1.0/tests/test_design_cache.py +300 -0
- beqforge-0.1.0/tests/test_design_cache_stores.py +194 -0
- beqforge-0.1.0/tests/test_design_channel_evidence.py +158 -0
- beqforge-0.1.0/tests/test_design_charts.py +113 -0
- beqforge-0.1.0/tests/test_design_corpus.py +97 -0
- beqforge-0.1.0/tests/test_design_design.py +75 -0
- beqforge-0.1.0/tests/test_design_designer.py +829 -0
- beqforge-0.1.0/tests/test_design_designer_server.py +467 -0
- beqforge-0.1.0/tests/test_design_device_rate.py +277 -0
- beqforge-0.1.0/tests/test_design_diagnose.py +303 -0
- beqforge-0.1.0/tests/test_design_evidence.py +247 -0
- beqforge-0.1.0/tests/test_design_evidence_excess.py +97 -0
- beqforge-0.1.0/tests/test_design_exclusions.py +208 -0
- beqforge-0.1.0/tests/test_design_explain.py +76 -0
- beqforge-0.1.0/tests/test_design_extraction.py +207 -0
- beqforge-0.1.0/tests/test_design_filters.py +725 -0
- beqforge-0.1.0/tests/test_design_frozen_cache.py +73 -0
- beqforge-0.1.0/tests/test_design_guard.py +282 -0
- beqforge-0.1.0/tests/test_design_harness.py +165 -0
- beqforge-0.1.0/tests/test_design_headroom.py +55 -0
- beqforge-0.1.0/tests/test_design_identify.py +110 -0
- beqforge-0.1.0/tests/test_design_jacobian.py +175 -0
- beqforge-0.1.0/tests/test_design_parallel.py +92 -0
- beqforge-0.1.0/tests/test_design_pipeline.py +555 -0
- beqforge-0.1.0/tests/test_design_playback.py +150 -0
- beqforge-0.1.0/tests/test_design_playback_headroom.py +251 -0
- beqforge-0.1.0/tests/test_design_publication.py +134 -0
- beqforge-0.1.0/tests/test_design_record.py +333 -0
- beqforge-0.1.0/tests/test_design_record_fingerprint.py +239 -0
- beqforge-0.1.0/tests/test_design_reference.py +269 -0
- beqforge-0.1.0/tests/test_design_references.py +147 -0
- beqforge-0.1.0/tests/test_design_rolloff.py +137 -0
- beqforge-0.1.0/tests/test_design_strategy_config.py +320 -0
- beqforge-0.1.0/tests/test_design_timings.py +67 -0
- beqforge-0.1.0/tests/test_design_verify.py +137 -0
- beqforge-0.1.0/tests/test_designer_server_startup.py +251 -0
- beqforge-0.1.0/tests/test_device_check_analyse.py +158 -0
- beqforge-0.1.0/tests/test_device_check_catalogue.py +84 -0
- beqforge-0.1.0/tests/test_device_check_catalogue_predict.py +97 -0
- beqforge-0.1.0/tests/test_device_check_cli.py +72 -0
- beqforge-0.1.0/tests/test_device_check_engines.py +208 -0
- beqforge-0.1.0/tests/test_device_check_evidence.py +77 -0
- beqforge-0.1.0/tests/test_device_check_examples.py +30 -0
- beqforge-0.1.0/tests/test_device_check_manifest.py +130 -0
- beqforge-0.1.0/tests/test_device_check_measurement.py +123 -0
- beqforge-0.1.0/tests/test_device_check_qualification.py +212 -0
- beqforge-0.1.0/tests/test_device_check_transactions.py +264 -0
- beqforge-0.1.0/tests/test_device_check_verify.py +92 -0
- beqforge-0.1.0/tests/test_extract_layout.py +179 -0
- beqforge-0.1.0/tests/test_optimiser.py +233 -0
- beqforge-0.1.0/tests/test_optimiser_cache.py +294 -0
- beqforge-0.1.0/tests/test_optimiser_report.py +160 -0
- beqforge-0.1.0/tests/test_package_boundaries.py +68 -0
- beqforge-0.1.0/tools/__init__.py +0 -0
- beqforge-0.1.0/tools/design_beq.py +499 -0
- beqforge-0.1.0/tools/designer_server.py +413 -0
- beqforge-0.1.0/tools/experiments/a1_sweep.py +307 -0
- beqforge-0.1.0/tools/experiments/compare_records.py +80 -0
- beqforge-0.1.0/tools/experiments/compare_verdicts.py +45 -0
- beqforge-0.1.0/tools/experiments/inject_variants.py +131 -0
- beqforge-0.1.0/tools/experiments/p14_compare.py +71 -0
- beqforge-0.1.0/tools/experiments/p14_jacobian.py +284 -0
- beqforge-0.1.0/tools/experiments/p14_run_pipeline.py +40 -0
- beqforge-0.1.0/tools/experiments/p14_surrogate.py +208 -0
- beqforge-0.1.0/tools/experiments/p18_compare_greedy.py +114 -0
- beqforge-0.1.0/tools/experiments/p18_compare_seeded.py +78 -0
- beqforge-0.1.0/tools/experiments/p18_compare_structure.py +73 -0
- beqforge-0.1.0/tools/experiments/p18_greedy.py +187 -0
- beqforge-0.1.0/tools/experiments/p18_seeded.py +139 -0
- beqforge-0.1.0/tools/experiments/p18_structure.py +86 -0
- beqforge-0.1.0/tools/experiments/p20_smooth_drift.py +97 -0
- beqforge-0.1.0/tools/experiments/probe.py +354 -0
- beqforge-0.1.0/tools/experiments/refit_probe.py +298 -0
- beqforge-0.1.0/tools/experiments/request_timing.py +229 -0
- beqforge-0.1.0/tools/experiments/score_injected.py +149 -0
- beqforge-0.1.0/tools/experiments/t8_floor_rules.py +106 -0
- beqforge-0.1.0/tools/extract.py +223 -0
- beqforge-0.1.0/tools/ledger_template.html +416 -0
- beqforge-0.1.0/tools/negative_corpus.py +192 -0
- beqforge-0.1.0/tools/optimiser_catalogue_report.py +550 -0
- beqforge-0.1.0/tools/prepare_device_check_helper.py +140 -0
- beqforge-0.1.0/tools/render_ledger.py +297 -0
- beqforge-0.1.0/tools/replay.py +109 -0
- beqforge-0.1.0/tools/seed_optimiser_cache.py +190 -0
- beqforge-0.1.0/tools/smoke_test_device_check.py +97 -0
- beqforge-0.1.0/tools/smoke_test_exe.py +281 -0
- beqforge-0.1.0/tools/smoke_test_install.py +163 -0
- beqforge-0.1.0/tools/summarise.py +124 -0
- beqforge-0.1.0/tools/validate_evidence.py +40 -0
- beqforge-0.1.0/uv.lock +981 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Build device-check preview
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- '**'
|
|
8
|
+
pull_request:
|
|
9
|
+
paths:
|
|
10
|
+
- 'beqforge_device_check/**'
|
|
11
|
+
- 'beqforge-device-check.spec'
|
|
12
|
+
- 'tools/prepare_device_check_helper.py'
|
|
13
|
+
- 'tools/smoke_test_device_check.py'
|
|
14
|
+
- 'packaging/device-check/**'
|
|
15
|
+
- '.github/workflows/build-device-check.yml'
|
|
16
|
+
- 'pyproject.toml'
|
|
17
|
+
- 'uv.lock'
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
defaults:
|
|
23
|
+
run:
|
|
24
|
+
shell: bash
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build:
|
|
28
|
+
name: Preview (${{ matrix.target }})
|
|
29
|
+
runs-on: ${{ matrix.os }}
|
|
30
|
+
timeout-minutes: 30
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
include:
|
|
35
|
+
- os: ubuntu-22.04
|
|
36
|
+
target: linux-x86_64
|
|
37
|
+
executable: beqforge-device-check
|
|
38
|
+
- os: windows-2022
|
|
39
|
+
target: windows-x86_64
|
|
40
|
+
executable: beqforge-device-check.exe
|
|
41
|
+
- os: macos-15
|
|
42
|
+
target: macos-arm64
|
|
43
|
+
executable: beqforge-device-check
|
|
44
|
+
- os: macos-15-intel
|
|
45
|
+
target: macos-x86_64
|
|
46
|
+
executable: beqforge-device-check
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v7
|
|
49
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
50
|
+
with:
|
|
51
|
+
enable-cache: true
|
|
52
|
+
- name: Install Linux audio and USB libraries
|
|
53
|
+
if: runner.os == 'Linux'
|
|
54
|
+
run: sudo apt-get update && sudo apt-get install -y libportaudio2 libusb-1.0-0
|
|
55
|
+
- name: Install locked measurement dependencies and pinned packager
|
|
56
|
+
run: |
|
|
57
|
+
uv sync --locked --extra device-check
|
|
58
|
+
uv pip install pyinstaller==6.22.3
|
|
59
|
+
- name: Prepare pinned native helper
|
|
60
|
+
run: uv run --extra device-check python tools/prepare_device_check_helper.py --target '${{ matrix.target }}' --out build/device-helper --cache build/helper-cache
|
|
61
|
+
- name: Diagnose folder build
|
|
62
|
+
env:
|
|
63
|
+
BEQFORGE_DEVICE_BUILD_MODE: onedir
|
|
64
|
+
run: |
|
|
65
|
+
uv run --extra device-check pyinstaller --clean --noconfirm --distpath dist/folder beqforge-device-check.spec
|
|
66
|
+
uv run --extra device-check python tools/smoke_test_device_check.py 'dist/folder/beqforge-device-check/${{ matrix.executable }}' --out 'build/folder test é'
|
|
67
|
+
- name: Build and verify single executable
|
|
68
|
+
run: |
|
|
69
|
+
uv run --extra device-check pyinstaller --clean --noconfirm --distpath dist/single beqforge-device-check.spec
|
|
70
|
+
uv run --extra device-check python tools/smoke_test_device_check.py 'dist/single/${{ matrix.executable }}' --out 'build/single test é' --package 'dist/preview-${{ matrix.target }}'
|
|
71
|
+
- uses: actions/upload-artifact@v7
|
|
72
|
+
with:
|
|
73
|
+
name: beqforge-device-check-preview-${{ matrix.target }}
|
|
74
|
+
path: dist/preview-${{ matrix.target }}
|
|
75
|
+
if-no-files-found: error
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
name: Build executable
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
defaults:
|
|
10
|
+
run:
|
|
11
|
+
shell: bash
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write # softprops/action-gh-release needs to create/attach to the release
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
tests:
|
|
18
|
+
name: Release tests
|
|
19
|
+
uses: ./.github/workflows/tests.yml
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
package:
|
|
24
|
+
name: Build Python package
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
- name: Build wheel and source distribution
|
|
34
|
+
run: uv build --out-dir dist
|
|
35
|
+
- name: Check release version
|
|
36
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
37
|
+
env:
|
|
38
|
+
RELEASE_TAG: ${{ github.ref_name }}
|
|
39
|
+
run: |
|
|
40
|
+
uv run --no-project --python 3.13 python - <<'PY'
|
|
41
|
+
import email
|
|
42
|
+
import os
|
|
43
|
+
import pathlib
|
|
44
|
+
import zipfile
|
|
45
|
+
|
|
46
|
+
wheel, = pathlib.Path("dist").glob("*.whl")
|
|
47
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
48
|
+
metadata, = (name for name in archive.namelist() if name.endswith(".dist-info/METADATA"))
|
|
49
|
+
version = email.message_from_bytes(archive.read(metadata))["Version"]
|
|
50
|
+
if os.environ["RELEASE_TAG"] != f"v{version}":
|
|
51
|
+
raise SystemExit(f"Release tag must be v{version}, matching the package version")
|
|
52
|
+
PY
|
|
53
|
+
- name: Validate package metadata
|
|
54
|
+
run: uvx twine check --strict dist/*
|
|
55
|
+
- name: Verify dependency profiles
|
|
56
|
+
run: |
|
|
57
|
+
for profile in base designer optimiser device-check all; do
|
|
58
|
+
uv run --no-project --python 3.13 python tools/smoke_test_install.py --wheel-dir dist --profile "$profile"
|
|
59
|
+
done
|
|
60
|
+
- name: Upload package distributions
|
|
61
|
+
uses: actions/upload-artifact@v7
|
|
62
|
+
with:
|
|
63
|
+
name: python-distributions
|
|
64
|
+
path: dist/*
|
|
65
|
+
if-no-files-found: error
|
|
66
|
+
|
|
67
|
+
create_release:
|
|
68
|
+
name: Create release
|
|
69
|
+
needs: [package, tests]
|
|
70
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@v7
|
|
74
|
+
with:
|
|
75
|
+
fetch-depth: 0 # changelog-generator diffs against the previous tag
|
|
76
|
+
|
|
77
|
+
- name: Generate changelog
|
|
78
|
+
id: changelog
|
|
79
|
+
uses: metcalfc/changelog-generator@v5.0.1
|
|
80
|
+
with:
|
|
81
|
+
myToken: ${{ secrets.GITHUB_TOKEN }}
|
|
82
|
+
|
|
83
|
+
- name: Create release
|
|
84
|
+
uses: softprops/action-gh-release@v3
|
|
85
|
+
with:
|
|
86
|
+
body: ${{ steps.changelog.outputs.changelog }}
|
|
87
|
+
env:
|
|
88
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
89
|
+
|
|
90
|
+
build:
|
|
91
|
+
name: Build (${{ matrix.os }})
|
|
92
|
+
# Manual runs skip release creation, but still require tests and package validation.
|
|
93
|
+
needs: [create_release, package, tests]
|
|
94
|
+
if: >-
|
|
95
|
+
!cancelled() && needs.tests.result == 'success' && needs.package.result == 'success' &&
|
|
96
|
+
(needs.create_release.result == 'success' || needs.create_release.result == 'skipped')
|
|
97
|
+
runs-on: ${{ matrix.os }}
|
|
98
|
+
strategy:
|
|
99
|
+
fail-fast: false
|
|
100
|
+
matrix:
|
|
101
|
+
include:
|
|
102
|
+
- os: ubuntu-latest
|
|
103
|
+
asset_name: beqforge-linux-x86_64
|
|
104
|
+
built_path: dist/beqforge
|
|
105
|
+
- os: macos-latest
|
|
106
|
+
asset_name: beqforge-macos-x86_64
|
|
107
|
+
built_path: dist/beqforge
|
|
108
|
+
- os: windows-latest
|
|
109
|
+
asset_name: beqforge-windows-x86_64.exe
|
|
110
|
+
built_path: dist/beqforge.exe
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/checkout@v7
|
|
113
|
+
|
|
114
|
+
- name: Install uv
|
|
115
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
116
|
+
with:
|
|
117
|
+
enable-cache: true
|
|
118
|
+
|
|
119
|
+
- name: Install dependencies
|
|
120
|
+
run: uv sync --locked --extra designer
|
|
121
|
+
|
|
122
|
+
- name: Install PyInstaller
|
|
123
|
+
run: uv pip install pyinstaller
|
|
124
|
+
|
|
125
|
+
- name: Build executable
|
|
126
|
+
run: uv run --extra designer pyinstaller --clean beqforge.spec
|
|
127
|
+
|
|
128
|
+
- name: Smoke-test the built executable
|
|
129
|
+
run: uv run --extra designer python tools/smoke_test_exe.py "${{ matrix.built_path }}"
|
|
130
|
+
|
|
131
|
+
- name: Rename artifact
|
|
132
|
+
run: cp "${{ matrix.built_path }}" "${{ matrix.asset_name }}"
|
|
133
|
+
|
|
134
|
+
- name: Upload workflow artifact
|
|
135
|
+
uses: actions/upload-artifact@v7
|
|
136
|
+
with:
|
|
137
|
+
name: ${{ matrix.asset_name }}
|
|
138
|
+
path: ${{ matrix.asset_name }}
|
|
139
|
+
|
|
140
|
+
- name: Attach to release
|
|
141
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
142
|
+
uses: softprops/action-gh-release@v3
|
|
143
|
+
with:
|
|
144
|
+
files: ${{ matrix.asset_name }}
|
|
145
|
+
env:
|
|
146
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
147
|
+
|
|
148
|
+
publish:
|
|
149
|
+
name: Publish Python package to PyPI
|
|
150
|
+
needs: [tests, package, build, create_release]
|
|
151
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
152
|
+
runs-on: ubuntu-latest
|
|
153
|
+
environment:
|
|
154
|
+
name: pypi
|
|
155
|
+
url: https://pypi.org/project/beqforge/
|
|
156
|
+
permissions:
|
|
157
|
+
contents: write
|
|
158
|
+
id-token: write
|
|
159
|
+
steps:
|
|
160
|
+
- name: Download verified distributions
|
|
161
|
+
uses: actions/download-artifact@v8
|
|
162
|
+
with:
|
|
163
|
+
name: python-distributions
|
|
164
|
+
path: dist
|
|
165
|
+
- name: Attach distributions to release
|
|
166
|
+
uses: softprops/action-gh-release@v3
|
|
167
|
+
with:
|
|
168
|
+
files: dist/*
|
|
169
|
+
env:
|
|
170
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
171
|
+
- name: Publish distributions
|
|
172
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: dependabot auto-merge
|
|
2
|
+
on: pull_request_target
|
|
3
|
+
|
|
4
|
+
permissions:
|
|
5
|
+
contents: write
|
|
6
|
+
pull-requests: write
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
auto-merge:
|
|
10
|
+
if: github.actor == 'dependabot[bot]'
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Fetch dependabot metadata
|
|
14
|
+
id: metadata
|
|
15
|
+
uses: dependabot/fetch-metadata@v3
|
|
16
|
+
with:
|
|
17
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
18
|
+
- name: Enable auto-merge for patch updates
|
|
19
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
|
|
20
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
21
|
+
env:
|
|
22
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
23
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
# Fits already control their own process parallelism. Avoid multiplying each worker
|
|
4
|
+
# by a BLAS thread pool on the small hosted runners.
|
|
5
|
+
env:
|
|
6
|
+
OPENBLAS_NUM_THREADS: '1'
|
|
7
|
+
OMP_NUM_THREADS: '1'
|
|
8
|
+
MKL_NUM_THREADS: '1'
|
|
9
|
+
VECLIB_MAXIMUM_THREADS: '1'
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
workflow_call:
|
|
13
|
+
push:
|
|
14
|
+
branches:
|
|
15
|
+
- '**'
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
test:
|
|
19
|
+
name: Test (${{ matrix.os }})
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v7
|
|
27
|
+
|
|
28
|
+
# brew's and choco's default ffmpeg both lack the libsoxr resampler tools/extract.py
|
|
29
|
+
# prefers, unlike Ubuntu's apt package — but extract.py now detects that at runtime and
|
|
30
|
+
# falls back to ffmpeg's default resampler, so any ordinary ffmpeg install is fine here.
|
|
31
|
+
- name: Install ffmpeg (Linux)
|
|
32
|
+
if: runner.os == 'Linux'
|
|
33
|
+
run: |
|
|
34
|
+
if command -v ffmpeg >/dev/null && command -v ffprobe >/dev/null; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
# The Azure mirror took over eight minutes to download ffmpeg's
|
|
38
|
+
# dependencies on a hosted runner. Use Ubuntu's archive mirror.
|
|
39
|
+
sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu|http://archive.ubuntu.com/ubuntu|g' /etc/apt/apt-mirrors.txt
|
|
40
|
+
sudo apt-get update
|
|
41
|
+
sudo apt-get install -y --no-install-recommends ffmpeg
|
|
42
|
+
|
|
43
|
+
- name: Install ffmpeg (macOS)
|
|
44
|
+
if: runner.os == 'macOS'
|
|
45
|
+
run: brew install ffmpeg
|
|
46
|
+
|
|
47
|
+
- name: Install ffmpeg (Windows)
|
|
48
|
+
if: runner.os == 'Windows'
|
|
49
|
+
run: choco install ffmpeg -y
|
|
50
|
+
|
|
51
|
+
- name: Install uv
|
|
52
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
53
|
+
with:
|
|
54
|
+
enable-cache: true
|
|
55
|
+
|
|
56
|
+
- name: Install dependencies
|
|
57
|
+
run: uv sync --locked --all-groups --extra designer
|
|
58
|
+
|
|
59
|
+
# the device-check tests run in their own job below, in parallel, with the extra installed
|
|
60
|
+
- name: Run tests
|
|
61
|
+
run: uv run --extra designer pytest --durations=25 --ignore-glob='tests/test_device_check_*.py'
|
|
62
|
+
|
|
63
|
+
device-check:
|
|
64
|
+
name: Device check (${{ matrix.os }})
|
|
65
|
+
runs-on: ${{ matrix.os }}
|
|
66
|
+
strategy:
|
|
67
|
+
fail-fast: false
|
|
68
|
+
matrix:
|
|
69
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v7
|
|
72
|
+
|
|
73
|
+
- name: Install uv
|
|
74
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
75
|
+
with:
|
|
76
|
+
enable-cache: true
|
|
77
|
+
|
|
78
|
+
# without the extra, most of these tests skip on importorskip('pyfar') rather than fail
|
|
79
|
+
- name: Install dependencies
|
|
80
|
+
run: uv sync --locked --all-groups --extra device-check
|
|
81
|
+
|
|
82
|
+
- name: Run device-check tests
|
|
83
|
+
shell: bash
|
|
84
|
+
run: uv run --extra device-check pytest --durations=25 tests/test_device_check_*.py
|
|
85
|
+
|
|
86
|
+
package-profiles:
|
|
87
|
+
name: Install profile (${{ matrix.profile }})
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
strategy:
|
|
90
|
+
fail-fast: false
|
|
91
|
+
matrix:
|
|
92
|
+
profile: [base, designer, optimiser, device-check, all]
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@v7
|
|
95
|
+
- uses: astral-sh/setup-uv@v10.2.0
|
|
96
|
+
with:
|
|
97
|
+
enable-cache: true
|
|
98
|
+
- name: Build the single distribution
|
|
99
|
+
run: uv build --out-dir dist
|
|
100
|
+
- name: Verify isolated wheel installation and command
|
|
101
|
+
run: uv run --no-project --python 3.13 python tools/smoke_test_install.py --wheel-dir dist --profile '${{ matrix.profile }}'
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
### JupyterNotebooks template
|
|
2
|
+
# gitignore template for Jupyter Notebooks
|
|
3
|
+
# website: http://jupyter.org/
|
|
4
|
+
|
|
5
|
+
.ipynb_checkpoints
|
|
6
|
+
*/.ipynb_checkpoints/*
|
|
7
|
+
|
|
8
|
+
# IPython
|
|
9
|
+
profile_default/
|
|
10
|
+
ipython_config.py
|
|
11
|
+
|
|
12
|
+
# Remove previous ipynb_checkpoints
|
|
13
|
+
# git rm -r .ipynb_checkpoints/
|
|
14
|
+
|
|
15
|
+
### Python template
|
|
16
|
+
# Byte-compiled / optimized / DLL files
|
|
17
|
+
__pycache__/
|
|
18
|
+
*.py[cod]
|
|
19
|
+
*$py.class
|
|
20
|
+
|
|
21
|
+
# C extensions
|
|
22
|
+
*.so
|
|
23
|
+
|
|
24
|
+
# Distribution / packaging
|
|
25
|
+
.Python
|
|
26
|
+
build/
|
|
27
|
+
develop-eggs/
|
|
28
|
+
dist/
|
|
29
|
+
downloads/
|
|
30
|
+
eggs/
|
|
31
|
+
.eggs/
|
|
32
|
+
lib/
|
|
33
|
+
lib64/
|
|
34
|
+
parts/
|
|
35
|
+
sdist/
|
|
36
|
+
var/
|
|
37
|
+
wheels/
|
|
38
|
+
share/python-wheels/
|
|
39
|
+
*.egg-info/
|
|
40
|
+
.installed.cfg
|
|
41
|
+
*.egg
|
|
42
|
+
MANIFEST
|
|
43
|
+
|
|
44
|
+
# PyInstaller
|
|
45
|
+
# Usually these files are written by a python script from a template
|
|
46
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
47
|
+
*.manifest
|
|
48
|
+
*.spec
|
|
49
|
+
!/beqforge.spec
|
|
50
|
+
|
|
51
|
+
# Installer logs
|
|
52
|
+
pip-log.txt
|
|
53
|
+
pip-delete-this-directory.txt
|
|
54
|
+
|
|
55
|
+
# Unit test / coverage reports
|
|
56
|
+
htmlcov/
|
|
57
|
+
.tox/
|
|
58
|
+
.nox/
|
|
59
|
+
.coverage
|
|
60
|
+
.coverage.*
|
|
61
|
+
.cache
|
|
62
|
+
nosetests.xml
|
|
63
|
+
coverage.xml
|
|
64
|
+
*.cover
|
|
65
|
+
*.py,cover
|
|
66
|
+
.hypothesis/
|
|
67
|
+
.pytest_cache/
|
|
68
|
+
cover/
|
|
69
|
+
|
|
70
|
+
# Translations
|
|
71
|
+
*.mo
|
|
72
|
+
*.pot
|
|
73
|
+
|
|
74
|
+
# Django stuff:
|
|
75
|
+
*.log
|
|
76
|
+
local_settings.py
|
|
77
|
+
db.sqlite3
|
|
78
|
+
db.sqlite3-journal
|
|
79
|
+
|
|
80
|
+
# Flask stuff:
|
|
81
|
+
instance/
|
|
82
|
+
.webassets-cache
|
|
83
|
+
|
|
84
|
+
# Scrapy stuff:
|
|
85
|
+
.scrapy
|
|
86
|
+
|
|
87
|
+
# Sphinx documentation
|
|
88
|
+
docs/_build/
|
|
89
|
+
|
|
90
|
+
# PyBuilder
|
|
91
|
+
.pybuilder/
|
|
92
|
+
target/
|
|
93
|
+
|
|
94
|
+
# Jupyter Notebook
|
|
95
|
+
|
|
96
|
+
# IPython
|
|
97
|
+
|
|
98
|
+
# pyenv
|
|
99
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
100
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
101
|
+
# .python-version
|
|
102
|
+
|
|
103
|
+
# pipenv
|
|
104
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
105
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
106
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
107
|
+
# install all needed dependencies.
|
|
108
|
+
#Pipfile.lock
|
|
109
|
+
|
|
110
|
+
# poetry
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
112
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
113
|
+
# commonly ignored for libraries.
|
|
114
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
115
|
+
#poetry.lock
|
|
116
|
+
|
|
117
|
+
# pdm
|
|
118
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
119
|
+
#pdm.lock
|
|
120
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
121
|
+
# in version control.
|
|
122
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
123
|
+
.pdm.toml
|
|
124
|
+
.pdm-python
|
|
125
|
+
.pdm-build/
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.venv
|
|
140
|
+
env/
|
|
141
|
+
venv/
|
|
142
|
+
ENV/
|
|
143
|
+
env.bak/
|
|
144
|
+
venv.bak/
|
|
145
|
+
|
|
146
|
+
# Spyder project settings
|
|
147
|
+
.spyderproject
|
|
148
|
+
.spyproject
|
|
149
|
+
|
|
150
|
+
# Rope project settings
|
|
151
|
+
.ropeproject
|
|
152
|
+
|
|
153
|
+
# mkdocs documentation
|
|
154
|
+
/site
|
|
155
|
+
|
|
156
|
+
# mypy
|
|
157
|
+
.mypy_cache/
|
|
158
|
+
.dmypy.json
|
|
159
|
+
dmypy.json
|
|
160
|
+
|
|
161
|
+
# Pyre type checker
|
|
162
|
+
.pyre/
|
|
163
|
+
|
|
164
|
+
# pytype static type analyzer
|
|
165
|
+
.pytype/
|
|
166
|
+
|
|
167
|
+
# Cython debug symbols
|
|
168
|
+
cython_debug/
|
|
169
|
+
|
|
170
|
+
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
171
|
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
172
|
+
|
|
173
|
+
# User-specific stuff
|
|
174
|
+
.idea/**/workspace.xml
|
|
175
|
+
.idea/**/tasks.xml
|
|
176
|
+
.idea/**/usage.statistics.xml
|
|
177
|
+
.idea/**/dictionaries
|
|
178
|
+
.idea/**/shelf
|
|
179
|
+
|
|
180
|
+
# AWS User-specific
|
|
181
|
+
.idea/**/aws.xml
|
|
182
|
+
|
|
183
|
+
# Generated files
|
|
184
|
+
.idea/**/contentModel.xml
|
|
185
|
+
|
|
186
|
+
# Sensitive or high-churn files
|
|
187
|
+
.idea/**/dataSources/
|
|
188
|
+
.idea/**/dataSources.ids
|
|
189
|
+
.idea/**/dataSources.local.xml
|
|
190
|
+
.idea/**/sqlDataSources.xml
|
|
191
|
+
.idea/**/dynamic.xml
|
|
192
|
+
.idea/**/uiDesigner.xml
|
|
193
|
+
.idea/**/dbnavigator.xml
|
|
194
|
+
|
|
195
|
+
# Gradle
|
|
196
|
+
.idea/**/gradle.xml
|
|
197
|
+
.idea/**/libraries
|
|
198
|
+
|
|
199
|
+
# Gradle and Maven with auto-import
|
|
200
|
+
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
201
|
+
# since they will be recreated, and may cause churn. Uncomment if using
|
|
202
|
+
# auto-import.
|
|
203
|
+
# .idea/artifacts
|
|
204
|
+
# .idea/compiler.xml
|
|
205
|
+
# .idea/jarRepositories.xml
|
|
206
|
+
# .idea/modules.xml
|
|
207
|
+
# .idea/*.iml
|
|
208
|
+
# .idea/modules
|
|
209
|
+
# *.iml
|
|
210
|
+
# *.ipr
|
|
211
|
+
|
|
212
|
+
# CMake
|
|
213
|
+
cmake-build-*/
|
|
214
|
+
|
|
215
|
+
# Mongo Explorer plugin
|
|
216
|
+
.idea/**/mongoSettings.xml
|
|
217
|
+
|
|
218
|
+
# File-based project format
|
|
219
|
+
*.iws
|
|
220
|
+
|
|
221
|
+
# IntelliJ
|
|
222
|
+
out/
|
|
223
|
+
|
|
224
|
+
# mpeltonen/sbt-idea plugin
|
|
225
|
+
.idea_modules/
|
|
226
|
+
|
|
227
|
+
# JIRA plugin
|
|
228
|
+
atlassian-ide-plugin.xml
|
|
229
|
+
|
|
230
|
+
# Cursive Clojure plugin
|
|
231
|
+
.idea/replstate.xml
|
|
232
|
+
|
|
233
|
+
# SonarLint plugin
|
|
234
|
+
.idea/sonarlint/
|
|
235
|
+
# see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
|
|
236
|
+
.idea/sonarlint.xml
|
|
237
|
+
|
|
238
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
239
|
+
com_crashlytics_export_strings.xml
|
|
240
|
+
crashlytics.properties
|
|
241
|
+
crashlytics-build.properties
|
|
242
|
+
fabric.properties
|
|
243
|
+
|
|
244
|
+
# Editor-based HTTP Client
|
|
245
|
+
.idea/httpRequests
|
|
246
|
+
http-client.private.env.json
|
|
247
|
+
|
|
248
|
+
# Android studio 3.1+ serialized cache file
|
|
249
|
+
.idea/caches/build_file_checksums.ser
|
|
250
|
+
|
|
251
|
+
# Apifox Helper cache
|
|
252
|
+
.idea/.cache/.Apifox_Helper
|
|
253
|
+
.idea/ApifoxUploaderProjectSetting.xml
|
|
254
|
+
|
|
255
|
+
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
|
256
|
+
.idea/**/copilot.data.migration.*.xml
|
|
257
|
+
|
|
258
|
+
data/
|
|
259
|
+
!beqoptimiser/data/
|
|
260
|
+
!beqoptimiser/data/seed.json.gz
|
|
261
|
+
!beqoptimiser/data/seed-manifest.json
|
|
262
|
+
|
|
263
|
+
# generated debug charts (PNGs, regenerated per run)
|
|
264
|
+
charts/
|
|
265
|
+
|
|
266
|
+
# generated output — .beq exports, the correction ledger, anything under --out/--charts-dir
|
|
267
|
+
out/
|
|
268
|
+
|
|
269
|
+
# Dedicated, reviewed F2 packaging recipe
|
|
270
|
+
!/beqforge-device-check.spec
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="JAVA_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$">
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
|
7
|
+
</content>
|
|
8
|
+
<orderEntry type="inheritedJdk" />
|
|
9
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
10
|
+
</component>
|
|
11
|
+
</module>
|