Skip to content

Release 0.0.7#12

Merged
HudsonGraeme merged 15 commits intomainfrom
dev
Mar 18, 2026
Merged

Release 0.0.7#12
HudsonGraeme merged 15 commits intomainfrom
dev

Conversation

@HudsonGraeme
Copy link
Copy Markdown
Owner

@HudsonGraeme HudsonGraeme commented Mar 18, 2026

Summary by CodeRabbit

  • New Features

    • Added support for OpenWrt 25.12+ apk packages while keeping opkg compatibility
  • Documentation

    • Clarified installation instructions and architecture lists for OpenWrt versions
    • Noted generated package paths per OpenWrt version
  • Style

    • Improved small danger button hover visuals
    • Switched action controls from icon-based to text-based buttons
  • Chores

    • Revamped CI build/packaging flow with per-architecture SDK caching, unified versioning, and consistent artifact uploads

OpenWrt 24.10+ defaults to APK as the package manager on many targets.
Users on these builds get "v2 package format error" when installing .ipk
files with `apk add`. This builds both formats per architecture so both
opkg and apk users are supported.
Allows triggering the full build matrix on PRs by adding a "run-build"
label. Builds also re-trigger on push if the label is present. PR builds
upload artifacts instead of attaching to a release.
When the APK build is not found, the package_name output is empty,
causing the upload path to resolve to /tmp/ which fails. Split uploads
into conditional steps gated on find_apk.outputs.found.
Extract a prepare job that builds dist/ once and shares it via artifact
instead of running Node.js setup + pnpm install + build in all 8 matrix
jobs. Cache the OpenWrt SDKs (pinned to 24.10.5) so subsequent runs
skip the ~200MB download per architecture. Version is computed once and
passed as a job output.
CONFIG_USE_APK is marked BROKEN in the 24.10 SDK and the apk host binary
is absent, so it cannot produce apk packages. Split into two parallel
job matrices: 24.10.5 SDK produces ipk for opkg devices, 25.12.0 SDK
(which ships apk as default) produces apk for devices running apk.
CONFIG_USE_APK is BROKEN in the 24.10 SDK. Use separate SDK versions:
24.10.5 for ipk (opkg devices), 25.12.0 for apk (apk devices).
Both matrices run in parallel after the shared prepare job.
Cache SDKs and deduplicate build assets across matrix
…k-package-format

# Conflicts:
#	.github/workflows/build-release.yml
- Replace unstyled btn-icon/btn-edit/btn-delete classes with existing action-btn-sm theme
- Add action-btn-sm.danger hover style for delete buttons
- Start login-view hidden to prevent flash while async auth check runs
APK mkpkg rejects versions with hyphens in the base (0.0.0-pr8). Use
dot-separated format (0.0.0.8) which is valid for both ipk and apk.
UI: Fix table action buttons and login flash
Add OpenWrt 25.12+ apk install commands alongside existing opkg
instructions. Update architecture list to use actual package suffixes.
Build both ipk and apk packages for OpenWrt 24.10+
@HudsonGraeme HudsonGraeme self-assigned this Mar 18, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Restructures the GitHub Actions pipeline into a prepare job that builds assets and determines package version, plus dependent build-ipk and build-apk jobs that reuse cached OpenWrt SDKs per target/arch, build versioned packages, and upload artifacts or create releases; updates README, CSS, index visibility, and action-button rendering.

Changes

Cohort / File(s) Summary
CI/CD Pipeline Restructuring
.github/workflows/build-release.yml
Replaces a single build job with a three-stage flow: prepare builds frontend assets, determines version (tag or PR), and uploads dist; build-ipk and build-apk depend on prepare, download dist, cache per-target/arch OpenWrt SDKs, update Makefile version, build packages, rename packages to versioned filenames, and publish artifacts or GitHub Release assets based on event type.
Documentation
README.md
Clarifies OpenWrt installation instructions for opkg (<=24.10) vs apk (>=25.12), updates supported architectures/targets lists, and documents generated package paths for each OpenWrt version.
UI Styling & Visibility
moci/app.css, moci/index.html
Adds hover style for .action-btn-sm.danger:hover (red border/text and glow). Adds hidden class to #login-view to keep login view concealed on initial render.
Action Button Rendering
moci/js/core.js
Refactors renderActionButtons(id) to output simplified text-based "EDIT" and "DELETE" buttons with action-btn-sm classes and data attributes, removing prior SVG/icon-based DOM structure.

Sequence Diagram(s)

sequenceDiagram
  participant GH as GitHub Actions
  participant Prepare as prepare job
  participant Dist as dist artifact
  participant BuildIPK as build-ipk job
  participant BuildAPK as build-apk job
  participant SDK as OpenWrt SDK cache
  participant Release as GitHub Release / Artifacts

  GH->>Prepare: trigger (push/tag or labeled PR)
  Prepare->>GH: checkout, setup node/pnpm, install, build minified assets
  Prepare->>Prepare: determine version (tag or PR-based)
  Prepare->>Dist: upload dist artifact (includes version)
  GH->>BuildIPK: start when prepare succeeds
  BuildIPK->>Dist: download dist artifact
  BuildIPK->>SDK: restore or download/extract SDK (per target/arch)
  BuildIPK->>BuildIPK: copy package files, update Makefile version, build IPK
  BuildIPK->>Release: upload IPK artifact or attach to Release
  GH->>BuildAPK: start when prepare succeeds
  BuildAPK->>Dist: download dist artifact
  BuildAPK->>SDK: restore or download/extract SDK (per target/arch)
  BuildAPK->>BuildAPK: copy package files, update Makefile version, build APK
  BuildAPK->>Release: upload APK artifact or attach to Release
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Rebrand to MoCI #5: Modifies the same GitHub Actions workflow and OpenWrt packaging paths/names; likely related to packaging/workflow changes.

Poem

🐰 I hopped through builds in three neat parts,
prepare made bundles and learned our parts.
SDK caches snug, packages dressed with care,
buttons turned to text — a lighter fare.
Hooray — release carrots wait everywhere! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Release 0.0.7' is vague and generic, using a non-descriptive term that doesn't convey meaningful information about the actual changeset. Replace with a descriptive title that summarizes the main changes, such as 'Refactor build workflow and UI components for v0.0.7' or identify the primary change to highlight.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.github/workflows/build-release.yml (1)

59-61: Consider fail-fast: false for both architecture matrices.

GitHub Actions defaults matrix fail-fast to true, so one broken target cancels the remaining builds in that matrix. For a multi-arch release workflow, that usually means fewer salvageable artifacts and less diagnostic signal from the same run. (docs.github.com)

Suggested change
     strategy:
+      fail-fast: false
       matrix:
         include:

Also applies to: 165-167

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-release.yml around lines 59 - 61, The matrix
strategy is currently using the default fail-fast behavior which cancels
remaining jobs on the first failure; update the workflow's strategy blocks that
define the matrix (the YAML blocks containing "strategy:" and "matrix:" with
"include:") to set fail-fast: false so each matrix runs all jobs even if one
fails—apply this change to both matrix definitions in the file (the two
"strategy: matrix:" sections).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build-release.yml:
- Around line 97-103: The SDK cache step ("Cache SDK" with id cache-sdk using
actions/cache@v4 and matrix.sdk_name) currently persists the entire SDK
including bin/packages which can leave old build outputs; modify the workflow to
(1) clean the SDK's prior build outputs (remove or empty bin/packages) before
building so cached stale packages can't be reused, and (2) change the "Find and
rename" logic to avoid head -n 1 by matching the exact expected filename (or
using a deterministic pattern with sort/most-recent selection) when selecting
the package to upload; alternatively restrict the cache path to exclude
bin/packages (or explicitly cache only source artifacts) to prevent packaging
artifacts from being cached.
- Around line 6-7: The workflow grants top-level write permissions to contents
during pull_request runs, exposing a write-scoped token; update the job
definitions for build-ipk and build-apk to add job-level permissions that
restrict token scope during PRs (e.g., set permissions.contents to read by
default and only enable write when github.event_name == 'release' or move write
to a separate release-publish job); modify the build-ipk and build-apk job
blocks to include a permissions stanza that conditionally sets contents to read
or to write only for release events so PR runs receive a read-only token.

In `@moci/index.html`:
- Line 16: The login page is unintentionally unreachable because both
`#login-view` and `#main-view` start with the hidden class; change the initial state
so at least the login UI can be shown immediately (remove the hidden class from
`#login-view` in index.html) or add a dedicated loading element instead of hiding
both screens, and update the session flow in moci/js/core.js (functions
autoLogin(), login(), and showLoginView()) to toggle the new loading state and
only hide/show `#main-view/`#login-view after session validation completes; ensure
fetch/login error paths call showLoginView() so users can manually sign in if
autoLogin fails.

---

Nitpick comments:
In @.github/workflows/build-release.yml:
- Around line 59-61: The matrix strategy is currently using the default
fail-fast behavior which cancels remaining jobs on the first failure; update the
workflow's strategy blocks that define the matrix (the YAML blocks containing
"strategy:" and "matrix:" with "include:") to set fail-fast: false so each
matrix runs all jobs even if one fails—apply this change to both matrix
definitions in the file (the two "strategy: matrix:" sections).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: df9a1b50-4723-4271-8a3d-96330b3d1ab1

📥 Commits

Reviewing files that changed from the base of the PR and between 6db0967 and f12551e.

📒 Files selected for processing (6)
  • .github/workflows/build-release.yml
  • README.md
  • moci/app.css
  • moci/app.js
  • moci/index.html
  • moci/js/core.js

Comment on lines +6 to +7
pull_request:
types: [labeled, synchronize]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat .github/workflows/build-release.yml

Repository: HudsonGraeme/MoCI

Length of output: 9362


🌐 Web query:

GitHub GITHUB_TOKEN permissions pull request same repository forked PR write access

💡 Result:

By default, the GITHUB_TOKEN in GitHub Actions workflows triggered by a pull_request event from a forked repository has read-only permissions to the base repository. This is a security feature to prevent malicious forks from writing to the target repo using workflows. Write access with GITHUB_TOKEN for forked PRs requires one of these: 1. Use the pull_request_target event trigger instead of pull_request. This grants read/write permissions to GITHUB_TOKEN (configurable via the permissions key) even for forks, and workflows run from the base branch. However, it has security risks: do not checkout the PR head sha or run untrusted code, as it can access secrets. See GitHub security guides for safe usage. 2. For private repositories, enable "Send write tokens to workflows from pull requests" in repo Actions settings (under Fork pull request workflows in private repositories). This allows GITHUB_TOKEN write permissions for pull_request events from forks, but pair with "Require approval for fork pull request workflows" for safety. GITHUB_TOKEN cannot write to the fork repository itself from the base repo workflow; it only has permissions scoped to the base repo. Permissions can be set in the workflow YAML with the 'permissions' key, e.g.: permissions: contents: write pull-requests: write Repo settings also control default GITHUB_TOKEN permissions (read-only or read/write).

Citations:


Restrict token scope for pull request jobs.

The workflow uses pull_request triggers with top-level permissions: contents: write. For same-repository PRs, this write scope is not automatically downgraded (unlike forked PRs). While the current code properly gates release uploads with if: github.event_name == 'release', the write-scoped token remains available in the job environment during PR runs, creating unnecessary exposure.

Add job-level permissions to restrict token scope for PR execution:

Example fix
build-ipk:
  permissions:
    contents: ${{ github.event_name == 'release' && 'write' || 'read' }}

Or simplify by setting read for matrix jobs and keeping write only in a separate release-publishing step.

Also applies to: build-apk job (same concern applies)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-release.yml around lines 6 - 7, The workflow grants
top-level write permissions to contents during pull_request runs, exposing a
write-scoped token; update the job definitions for build-ipk and build-apk to
add job-level permissions that restrict token scope during PRs (e.g., set
permissions.contents to read by default and only enable write when
github.event_name == 'release' or move write to a separate release-publish job);
modify the build-ipk and build-apk job blocks to include a permissions stanza
that conditionally sets contents to read or to write only for release events so
PR runs receive a read-only token.

Comment on lines +97 to 103
- name: Cache SDK
id: cache-sdk
uses: actions/cache@v4
with:
version: 9

- name: Install Node dependencies
run: pnpm install --frozen-lockfile

- name: Build minified assets
run: pnpm run build
path: ${{ matrix.sdk_name }}
key: sdk-${{ matrix.sdk_name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && find . -name "build-release.yml" -type f

Repository: HudsonGraeme/MoCI

Length of output: 98


🏁 Script executed:

cd "$(git rev-parse --show-toplevel)" && cat -n .github/workflows/build-release.yml | head -n 260

Repository: HudsonGraeme/MoCI

Length of output: 10976


The SDK cache can publish stale packages.

The cache step persists the entire SDK directory, including bin/packages/. When a cached SDK is reused, old build outputs remain. The "Find and rename" steps use head -n 1 to select the first matching file, which is non-deterministic and can pick an older package if multiple versions exist. This risks uploading a stale package to the release instead of the current build output.

Clean prior package outputs before each build and use exact filename matching:

Suggested hardening
       - name: Build ipk package
         working-directory: ${{ matrix.sdk_name }}
         run: |
+          find bin/packages -name 'moci_*.ipk' -delete
           make defconfig
           make package/moci/compile V=s

       - name: Find and rename ipk
         id: find_ipk
         working-directory: ${{ matrix.sdk_name }}
         run: |
+          VERSION="${{ needs.prepare.outputs.version }}"
-          IPK_FILE=$(find bin/packages -name "moci_*.ipk" | head -n 1)
+          IPK_FILE=$(find bin/packages -name "moci_${VERSION}-r1_${{ matrix.arch }}.ipk" -print -quit)
           if [ -z "$IPK_FILE" ]; then
             echo "Error: ipk package not found!"
             exit 1
           fi
-          VERSION="${{ needs.prepare.outputs.version }}"
           NEW_NAME="moci_${VERSION}-r1_${{ matrix.arch }}.ipk"

       - name: Build apk package
         working-directory: ${{ matrix.sdk_name }}
         run: |
+          find bin/packages -name 'moci-*.apk' -delete
           make defconfig
           make package/moci/compile V=s

       - name: Find and rename apk
         id: find_apk
         working-directory: ${{ matrix.sdk_name }}
         run: |
+          VERSION="${{ needs.prepare.outputs.version }}"
-          APK_FILE=$(find bin/packages -name "moci*.apk" | head -n 1)
+          APK_FILE=$(find bin/packages -name "moci-${VERSION}-r1.apk" -print -quit)
           if [ -z "$APK_FILE" ]; then
             echo "Error: apk package not found!"
             exit 1
           fi
-          VERSION="${{ needs.prepare.outputs.version }}"
           NEW_NAME="moci_${VERSION}-r1_${{ matrix.arch }}.apk"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-release.yml around lines 97 - 103, The SDK cache
step ("Cache SDK" with id cache-sdk using actions/cache@v4 and matrix.sdk_name)
currently persists the entire SDK including bin/packages which can leave old
build outputs; modify the workflow to (1) clean the SDK's prior build outputs
(remove or empty bin/packages) before building so cached stale packages can't be
reused, and (2) change the "Find and rename" logic to avoid head -n 1 by
matching the exact expected filename (or using a deterministic pattern with
sort/most-recent selection) when selecting the package to upload; alternatively
restrict the cache path to exclude bin/packages (or explicitly cache only source
artifacts) to prevent packaging artifacts from being cached.

<body>
<div id="app">
<div id="login-view" class="view">
<div id="login-view" class="view hidden">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't start with both views hidden.

Line 16 makes the login screen invisible until moci/js/core.js:80-99 finishes session validation / auto-login and showLoginView() in moci/js/core.js:331-334 removes hidden. Because #main-view is already hidden and autoLogin() eventually calls login(), which still uses a plain fetch, a stale session or hanging /ubus request now leaves the user on a blank page with no way to log in manually.

🛠 Minimal fix
-			<div id="login-view" class="view hidden">
+			<div id="login-view" class="view">

If the goal is to avoid a login flash for valid sessions, add a dedicated loading state instead of hiding both screens.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div id="login-view" class="view hidden">
<div id="login-view" class="view">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@moci/index.html` at line 16, The login page is unintentionally unreachable
because both `#login-view` and `#main-view` start with the hidden class; change the
initial state so at least the login UI can be shown immediately (remove the
hidden class from `#login-view` in index.html) or add a dedicated loading element
instead of hiding both screens, and update the session flow in moci/js/core.js
(functions autoLogin(), login(), and showLoginView()) to toggle the new loading
state and only hide/show `#main-view/`#login-view after session validation
completes; ensure fetch/login error paths call showLoginView() so users can
manually sign in if autoLogin fails.

- Restrict top-level permissions to read, grant write only at job level
  where release uploads need it
- Clean bin/packages before building to prevent stale cached artifacts
  from being picked up by find
- Set fail-fast: false on both matrix strategies so all arch builds
  complete independently
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
.github/workflows/build-release.yml (1)

59-60: ⚠️ Potential issue | 🟠 Major

Restrict write-scoped GITHUB_TOKEN during PR builds.

Line 59 and Line 169 still grant contents: write for the full job, including pull_request runs. Even with release-only upload steps, PR job steps still execute with a write-scoped token. Limit write scope to a dedicated release-publish job (or otherwise ensure build jobs run with read-only permissions).

For GitHub Actions pull_request events from the same repository, if a job sets permissions.contents: write, does GITHUB_TOKEN keep write access for all steps in that job even when the release upload step is gated by if: github.event_name == 'release'?

Also applies to: 169-170

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-release.yml around lines 59 - 60, The workflow
grants a write-scoped GITHUB_TOKEN via the permissions: contents: write setting
for jobs that run on PRs; change the default job permissions to contents: read
(or remove write) so pull_request builds run with read-only token, and move
contents: write to only the dedicated release-publish job (the job that performs
release uploads and is gated with if: github.event_name == 'release') so only
that job has write scope; update the workflow to set permissions: contents:
write inside the release-publish job definition and ensure all other jobs use
contents: read.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.github/workflows/build-release.yml:
- Around line 59-60: The workflow grants a write-scoped GITHUB_TOKEN via the
permissions: contents: write setting for jobs that run on PRs; change the
default job permissions to contents: read (or remove write) so pull_request
builds run with read-only token, and move contents: write to only the dedicated
release-publish job (the job that performs release uploads and is gated with if:
github.event_name == 'release') so only that job has write scope; update the
workflow to set permissions: contents: write inside the release-publish job
definition and ensure all other jobs use contents: read.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 30ff874a-16a1-4f5a-8921-97e155437446

📥 Commits

Reviewing files that changed from the base of the PR and between f12551e and bb867c8.

📒 Files selected for processing (1)
  • .github/workflows/build-release.yml

@HudsonGraeme HudsonGraeme merged commit 1ea880b into main Mar 18, 2026
4 checks passed
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