Skip to content

Push each build to openipc.org once; stop uploading size-report sidecars to releases - #170

Merged
openipc-ai merged 3 commits into
masterfrom
push-builds-to-openipc-org
Sep 26, 2026
Merged

openipc-ai merged 3 commits into
masterfrom
push-builds-to-openipc-org

Conversation

@openipc-ai

@openipc-ai openipc-ai commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Each builder nightly now tells openipc.org about itself once, directly. The sizes.* sidecars per dated release are no longer uploaded.

What changes

  • publish job: stops uploading sizes.* to the dated release. Only device tarballs are uploaded now, and they still go to the dated release, nightly and latest.
    • The size report is still generated.
    • It travels in a small reports-<platform> artifact kept for 7 days.
  • New report job runs after publish and can be re-run on its own.
    • It reads each published tarball's size and sha256 from the release (gh release view --json assets).
    • The payload carries device tarballs and size reports, and no aliases.
    • It POSTs one gzip JSON document to https://openipc.org/api/v1/builds, authenticated with a GitHub Actions OIDC token for the audience https://openipc.org.
    • The job has id-token: write and contents: read. No secret is added.
    • It retries on 5xx and fails on 4xx with the response printed.
    • The push is idempotent per build id.
  • Tests: test_push_build.py, 18 cases, run by lint.yml.

Unchanged: gh-pages manifest.json and manifest.flat, which cameras' sysupgrade reads; cleanup.yml; the nightly release body.

The receiving side is OpenIPC/website#311. openipc.org already holds the history these sidecars carried, imported once; the old files on past releases age out through cleanup.yml. The contract is at https://github.com/OpenIPC/website/blob/builds-from-ci/service/internal/builds/PUSH.md.

openipc-ai and others added 2 commits September 26, 2026 13:15
…releases

The per-device sizes.*.json files uploaded to each dated release existed
for the firmware explorer to poll. Releases are for firmware, and
openipc.org no longer polls GitHub.

- publish uploads the device images only, to the dated release as to
  nightly and latest. The size reports still travel as fw-* artifacts. With
  no images, no dated release is created.
- A new report job, after publish and outside ci-gate, pushes the build to
  https://openipc.org/api/v1/builds once: the images with sha256 and each
  device's size report. It authenticates with its GitHub OIDC token (audience
  https://openipc.org); no secret is stored. The push is idempotent by build
  id, so the job can be re-run by itself.
- push_build.py, soc_aliases.py and test_push_build.py are copies of
  OpenIPC/firmware's. lint.yml runs the tests.

Contract: OpenIPC/website service/internal/builds/PUSH.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The report job no longer needs the one-day fw-* artifacts:

- Each device image's size and sha256 come from the dated release after
  publish (`gh release view <tag> --json assets`; GitHub computes the digest
  on upload). An image with no digest fails the push.
- The size report travels in its own reports-<device> artifact, kept 7
  days; fw-* carries only the image and keeps its retention. A push that
  could not reach openipc.org can be re-run for a week.

push_build.py and its tests are refreshed from OpenIPC/firmware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Push published builds to openipc.org via OIDC

✨ Enhancement ⚙️ Configuration changes 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Report each published build directly to openipc.org using secretless GitHub OIDC authentication.
• Store size reports in seven-day artifacts while releases retain only firmware tarballs.
• Decouple reporting from publication and test payload, authentication, and retry behavior.
Diagram

sequenceDiagram
    participant B as Build Matrix
    participant A as Artifact Store
    participant P as Publish Job
    participant G as GitHub Releases
    participant R as Report Job
    participant O as GitHub OIDC
    participant W as openipc.org
    B->>A: Upload firmware and reports
    A->>P: Download firmware
    P->>G: Upload tarballs only
    A->>R: Download reports
    R->>G: Read asset size and digest
    R->>O: Request audience token
    O-->>R: Return OIDC token
    R->>W: POST gzip build JSON
    W-->>R: Accept build idempotently
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Retain release sidecars and polling
  • ➕ Keeps firmware and size metadata together in GitHub releases.
  • ➕ Preserves the former consumer model without a new push job.
  • ➖ Clutters releases with non-firmware assets.
  • ➖ Requires openipc.org to poll GitHub and detect new builds.
  • ➖ Consumes additional release upload and API capacity.
2. Report from downloaded firmware artifacts
  • ➕ Avoids querying GitHub Releases for asset metadata.
  • ➕ Can calculate hashes entirely within GitHub Actions.
  • ➖ Requires retaining and downloading large firmware artifacts again.
  • ➖ Local hashes may not independently describe the final release assets.
  • ➖ Makes reporting dependent on short-lived firmware artifacts.

Recommendation: Keep the PR's post-publication push design. Querying GitHub Releases provides authoritative metadata for the exact downloadable bytes, while separate seven-day report artifacts permit reruns without retaining large firmware artifacts. OIDC avoids secret lifecycle costs, and placing the idempotent report job outside the CI gate prevents openipc.org availability from invalidating an otherwise successful release.

Files changed (6) +681 / -21

Enhancement (3) +419 / -20
push_build.pyAdd OIDC-authenticated build reporting client +260/-0

Add OIDC-authenticated build reporting client

• Introduces a standard-library client that assembles build, release asset, and platform report metadata into the openipc.org contract. It retrieves GitHub-provided asset digests, sends gzip JSON with an audience-scoped OIDC token, retries transient failures, and supports offline payload generation.

.github/scripts/push_build.py

soc_aliases.pyAdd shared SoC alias scanner +59/-0

Add shared SoC alias scanner

• Parses firmware defconfigs into deterministic alias-to-model mappings. It ignores self-aliases and reports conflicting claims while retaining the first mapping.

.github/scripts/soc_aliases.py

master.ymlSeparate report artifacts and push published builds +100/-20

Separate report artifacts and push published builds

• Stops uploading size-report sidecars to releases and retains them as optional seven-day artifacts. Adds a post-publication report job that reads authoritative tarball metadata from the dated release and sends one OIDC-authenticated build payload to openipc.org without affecting the main CI gate.

.github/workflows/master.yml

Tests (2) +260 / -0
test_push_build.pyTest build payloads, aliases, OIDC, and transport failures +252/-0

Test build payloads, aliases, OIDC, and transport failures

• Adds 18 unit tests covering release metadata, platform reports, missing data, U-Boot fallback hashing, alias conflicts, OIDC token requests, compressed POST bodies, and retry behavior.

.github/scripts/test_push_build.py

lint.ymlRun build-push tests in lint CI +8/-0

Run build-push tests in lint CI

• Adds the reporting scripts to push path filters and executes the new unit test suite. This validates the otherwise unattended nightly reporting path on pull requests and relevant master changes.

.github/workflows/lint.yml

Other (1) +2 / -1
ci-matrix.pyExclude reporting scripts from firmware rebuild selection +2/-1

Exclude reporting scripts from firmware rebuild selection

• Classifies the build-push implementation, alias scanner, and tests as CI-only scripts. Changes to these files therefore avoid triggering the device build matrix.

.github/scripts/ci-matrix.py

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Devices vanish when size reports fail ✓ Resolved 🐞 Bug ≡ Correctness
Description
collect_platforms recognizes only openipc.--.tgz assets, while compound-device images are
published as -nor.tgz or -nand.tgz. When the intentionally optional size-report step fails or
produces no JSON, those compound images cannot create their own platform entries even though they
are included in the build's asset list.
Code

.github/scripts/push_build.py[51]

+FIRMWARE_ASSET_RE = re.compile(r"^openipc\.([^.]+?)-(nor|nand|emmc|sd)-([a-z0-9]+)\.tgz$")
Evidence
The workflow renames compound outputs to names without the openipc. prefix and tolerates failure
of the only alternate platform source, while the new reporting script derives fallback platforms
exclusively through the narrower regular expression.

.github/scripts/push_build.py[49-52]
.github/scripts/push_build.py[119-145]
.github/workflows/master.yml[340-363]
.github/workflows/master.yml[365-388]
.github/workflows/master.yml[700-713]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Compound-device firmware tarballs do not match `FIRMWARE_ASSET_RE`, so a published device is omitted from `platforms` whenever its optional size report is unavailable.
## Fix Focus Areas
- .github/scripts/push_build.py[49-52]
- .github/scripts/push_build.py[119-145]
- .github/workflows/master.yml[340-388]
- .github/scripts/test_push_build.py[93-113]
## Recommended Fix
Extend platform extraction to recognize both standard `openipc.<board>-<storage>-<edition>.tgz` names and compound `<matrix-platform>-<storage>.tgz` names. Add tests proving that compound tarballs create platform entries with and without corresponding report files.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/scripts/push_build.py
From Qodo's review of #170:

- Compound devices publish <matrix platform>-<storage>.tgz, with no
  openipc. prefix, so push_build.py dropped any whose size report was
  missing. It now recognises both naming schemes; tests cover each, with and
  without report files, and a report and its tarball being one device.
- The report job downloaded reports-* before actions/checkout, which cleans
  the workspace, so every push would have lost its reports. Checkout now
  comes first and the reports land in runner.temp.
- A guard tells "no reports produced" from "reports lost": if the matrix
  uploaded reports-* artifacts and none arrived, the push fails instead of
  sending devices without their detail (actions: read, to count them).
- The job runs only this repository's push script; the artifacts are read
  as data. push_build.py and its tests are refreshed from OpenIPC/firmware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@openipc-ai

Copy link
Copy Markdown
Contributor Author

Fixed in fea4a99:

  • Compound devices: push_build.py now also recognises <matrix platform>-<storage>.tgz (no openipc. prefix), so a compound device whose size report is missing is still listed. Tests cover both naming schemes, with and without reports, and a report and its tarball counting as one device.
  • report ordering: it had the same download-before-checkout bug as firmware. Checkout is now first and the reports land in runner.temp/reports.
  • Lost-reports guard: if reports-* artifacts were uploaded but none arrived, the push fails loudly.
  • The job runs only this repo's script, and push_build.py and its tests are refreshed from OpenIPC/firmware. Tests: 22, all passing. actionlint and the self-tests are clean.

@openipc-ai
openipc-ai merged commit 3f53bec into master Sep 26, 2026
97 of 125 checks passed
@openipc-ai
openipc-ai deleted the push-builds-to-openipc-org branch September 26, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant