-
Notifications
You must be signed in to change notification settings - Fork 0
chore(deps): sync fork-compatible helper updates #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e1496a2
d12bcb1
bfcd44f
3a3288e
2e546af
6317d1a
84fcfcf
4e174dd
069fd4a
f715e9b
cba539b
270528f
bd7e2bb
126cf4a
f624767
df3a56b
04fb697
e91858b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,253 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Reusable ROM build | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_call: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| rom-family: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| device-id: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| root: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| magisk-preinit-device: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| update-channel: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| compatible-sepolicy-patching: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| allow-unauthorized-adb: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| release-type: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| publish: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| secrets: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| AVB_KEY: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| CERT_OTA: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| OTA_KEY: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PASSPHRASE_AVB: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PASSPHRASE_OTA: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| EMAIL: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_INCREMENTAL: 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| DEVICE_NAME: ${{ inputs.device-id }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| INTERACTIVE_MODE: false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ROM_FAMILY: ${{ inputs.rom-family }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| GRAPHENEOS_UPDATE_CHANNEL: ${{ inputs.update-channel }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| OUTPUT_SCOPE: ${{ inputs.publish && inputs.release-type != 'build-only' && 'published' || 'local-unpublished' }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUST_BACKTRACE: short | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUSTUP_MAX_RETRIES: 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GH_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| RELEASE_TYPE: ${{ inputs.release-type }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| build: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Validate build request | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_DEBUG: ${{ inputs.allow-unauthorized-adb }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_MAS_COMPATIBLE_SEPOLICY: ${{ inputs.compatible-sepolicy-patching }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_ROOT: ${{ inputs.root }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| MAGISK_PREINIT_REQUEST: ${{ inputs.magisk-preinit-device }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "${ADDITIONALS_ROOT}" == "true" && -z "${MAGISK_PREINIT_REQUEST}" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::magisk-preinit-device is required for rooted builds" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "${RELEASE_TYPE}" in | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| default|build-only|force-publish) ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| *) echo "::error::Unknown release type"; exit 1 ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| esac | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout shared implementation | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v7 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Enforce profile output policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_DEBUG: ${{ inputs.allow-unauthorized-adb }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_MAS_COMPATIBLE_SEPOLICY: ${{ inputs.compatible-sepolicy-patching }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_ROOT: ${{ inputs.root }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| source src/declarations.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| source src/rom_profiles.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolve_rom_profile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| enforce_output_policy "${OUTPUT_SCOPE}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Install Rust stable | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: dtolnay/rust-toolchain@master | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| toolchain: stable 2 weeks ago | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Cache Rust dependencies | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: Swatinem/rust-cache@v2.9.2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Install Python | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-python@v7 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| python-version: "3.12-dev" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+111
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🌐 Web query:
💡 Result: In the actions/setup-python action, the x.y-dev syntax (such as 3.12-dev) is a specific notation used to automatically install the latest available patch version of a given minor release, which explicitly includes alpha, beta, and release candidate (pre-release) versions [1][2]. Key behaviors regarding this syntax and pre-release handling include: 1. Automatic Inclusion: Unlike standard version specifiers (e.g., 3.12), the 3.y-dev notation is designed to include pre-release versions for the specified minor version automatically, without requiring any additional configuration [1][2]. 2. Purpose of allow-prereleases: The separate allow-prereleases input (which defaults to false) serves a different purpose [1][3]. It allows the action to fall back to a pre-release version of Python only when a matching General Availability (GA) version does not yet exist for a specified minor version (e.g., specifying python-version: 3.14 with allow-prereleases: true when 3.14 GA has not been released) [1][4]. 3. Interaction: The x.y-dev syntax is distinct from the fallback behavior controlled by allow-prereleases [1][4]. You do not need to set allow-prereleases: true to use the x.y-dev syntax to fetch the latest pre-release for that minor version [1][2]. In summary, if you use 3.12-dev, the action will resolve to the latest patch or pre-release available for the 3.12 series by default [1][2]. If you use 3.12 (without -dev), it will only install a stable GA release unless you explicitly set allow-prereleases: true [1][3][4]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Workflow relevant sections:"
if [ -f .github/workflows/build-rom.yml ]; then
nl -ba .github/workflows/build-rom.yml | sed -n '1,180p'
else
echo "workflow file missing"
fi
echo
echo "Check whether 3.12-dev is an in-development prerelease in current pythons repository:"
python3 - <<'PY'
from urllib.request import urlopen, Request
import json
versions = json.load(urlopen(Request("https://raw.githubusercontent.com/python/cpython/main/versions.json", headers={"User-Agent":"README-verification"})))
print("versions:", versions)
PYRepository: 0cwa/PixeneOS Length of output: 219 🏁 Script executed: #!/bin/bash
set -e
export PYTHONUNBUFFERED=1
echo "Workflow file exists:"
test -f .github/workflows/build-rom.yml && echo yes || echo no
echo
echo "build-rom.yml relevant lines:"
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/build-rom.yml")
print("exists?", p.exists())
if p.exists():
lines = p.read_text().splitlines()
for i in range(max(0, 105), min(len(lines), 130)):
print(f"{i+1:4}: {lines[i]}")
PY
echo
echo "Releases/build steps and Python usage:"
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/build-rom.yml")
if p.exists():
lines = p.read_text().splitlines()
for needle in ["release", "sign", "build", "python", "python-version"]:
matches = [(i+1, line) for i, line in enumerate(lines) if needle.lower() in line.lower()]
print(needle + ":")
for n, line in matches[:30]:
print(f"{n:4}: {line}")
PY
echo
echo "Check python x.y-dev in CPython versions.json:"
python3 - <<'PY'
from urllib.request import urlopen, Request
import json
try:
versions = json.load(urlopen(Request("https://raw.githubusercontent.com/python/cpython/main/versions.json", headers={"User-Agent":"README-verification"})))
except Exception as exc:
print("FETCH_ERROR", type(exc).__name__, str(exc))
raise
print("python_version:", versions.get("python_version"))
print("versions:", versions.get("versions"))
PYRepository: 0cwa/PixeneOS Length of output: 5596 Pin the Python interpreter for the signing path. This job installs 🧰 Tools🪛 zizmor (1.29.0)[error] 112-112: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Setup signing environment | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "KEYS_AVB_BASE64<<EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "${{ secrets.AVB_KEY }}" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "KEYS_CERT_OTA_BASE64<<EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "${{ secrets.CERT_OTA }}" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "KEYS_OTA_BASE64<<EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "${{ secrets.OTA_KEY }}" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "EOF" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+116
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Pass the signing secrets through Lines 119-127 expand secrets directly into the script body. The heredoc delimiter is the fixed string 🔒 Proposed fix - name: Setup signing environment
shell: bash
+ env:
+ AVB_KEY: ${{ secrets.AVB_KEY }}
+ CERT_OTA: ${{ secrets.CERT_OTA }}
+ OTA_KEY: ${{ secrets.OTA_KEY }}
run: |
- echo "KEYS_AVB_BASE64<<EOF" >> "${GITHUB_ENV}"
- echo "${{ secrets.AVB_KEY }}" >> "${GITHUB_ENV}"
- echo "EOF" >> "${GITHUB_ENV}"
- echo "KEYS_CERT_OTA_BASE64<<EOF" >> "${GITHUB_ENV}"
- echo "${{ secrets.CERT_OTA }}" >> "${GITHUB_ENV}"
- echo "EOF" >> "${GITHUB_ENV}"
- echo "KEYS_OTA_BASE64<<EOF" >> "${GITHUB_ENV}"
- echo "${{ secrets.OTA_KEY }}" >> "${GITHUB_ENV}"
- echo "EOF" >> "${GITHUB_ENV}"
+ delimiter="$(openssl rand -hex 16)"
+ {
+ printf '%s<<%s\n%s\n%s\n' KEYS_AVB_BASE64 "${delimiter}" "${AVB_KEY}" "${delimiter}"
+ printf '%s<<%s\n%s\n%s\n' KEYS_CERT_OTA_BASE64 "${delimiter}" "${CERT_OTA}" "${delimiter}"
+ printf '%s<<%s\n%s\n%s\n' KEYS_OTA_BASE64 "${delimiter}" "${OTA_KEY}" "${delimiter}"
+ } >> "${GITHUB_ENV}"This also resolves the SC2129 shellcheck finding reported by actionlint on this step. 📝 Committable suggestion
Suggested change
🧰 Tools🪛 actionlint (1.7.12)[error] 118-118: shellcheck reported issue in this script: SC2129:style:1:1: Consider using { cmd1; cmd2; } >> file instead of individual redirects (shellcheck) 🪛 zizmor (1.29.0)[warning] 120-120: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [warning] 123-123: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [warning] 126-126: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Patch OTA | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_DEBUG: ${{ inputs.allow-unauthorized-adb }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_MAS_COMPATIBLE_SEPOLICY: ${{ inputs.compatible-sepolicy-patching }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_ROOT: ${{ inputs.root }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| CLEANUP: true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| MAGISK_PREINIT: ${{ inputs.magisk-preinit-device }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PASSPHRASE_AVB: ${{ secrets.PASSPHRASE_AVB }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PASSPHRASE_OTA: ${{ secrets.PASSPHRASE_OTA }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| source src/main.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "GRAPHENEOS_OTA_TARGET=${GRAPHENEOS[OTA_TARGET]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "GRAPHENEOS_VERSION=${VERSION[GRAPHENEOS]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "MODULE_SELECTION_FINGERPRINT=${MODULE_SELECTION_FINGERPRINT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "OUTPUTS_PATCHED_OTA=${OUTPUTS[PATCHED_OTA]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "WORKDIR=${WORKDIR}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Record build metadata | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| selection_metadata="${OUTPUTS_PATCHED_OTA}.selection.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| python3 - \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${selection_metadata}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${ROM_FAMILY}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${DEVICE_NAME}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${MODULE_SELECTION_FINGERPRINT}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${OUTPUT_SCOPE}" <<'PY' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import pathlib | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| path, rom_family, device, fingerprint, output_scope = sys.argv[1:] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| data = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "device": device, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "module_selection_fingerprint": fingerprint, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "output_scope": output_scope, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "rom_family": rom_family, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "schema_version": 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pathlib.Path(path).write_text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| json.dumps(data, indent=2, sort_keys=True) + "\n", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| encoding="utf-8", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PY | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "SELECTION_METADATA=${selection_metadata}" >> "${GITHUB_ENV}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "ROM family: ${ROM_FAMILY}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Device: ${DEVICE_NAME}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Selection fingerprint: ${MODULE_SELECTION_FINGERPRINT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Output scope: ${OUTPUT_SCOPE}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } >> "${GITHUB_STEP_SUMMARY}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Re-enforce publication policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: inputs.publish && inputs.release-type != 'build-only' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_DEBUG: ${{ inputs.allow-unauthorized-adb }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_MAS_COMPATIBLE_SEPOLICY: ${{ inputs.compatible-sepolicy-patching }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ADDITIONALS_ROOT: ${{ inputs.root }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| source src/declarations.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| source src/rom_profiles.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolve_rom_profile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| enforce_publication_evidence "${OUTPUT_SCOPE}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ "${MODULE_SELECTION_FINGERPRINT}" =~ ^[0-9a-f]{64}$ ]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Generate changelog | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: inputs.publish && inputs.release-type != 'build-only' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "ROM family: ${ROM_FAMILY}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Device: ${DEVICE_NAME}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Module-selection fingerprint: ${MODULE_SELECTION_FINGERPRINT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } > "${GITHUB_WORKSPACE}-CHANGELOG.txt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish GitHub release | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: inputs.publish && inputs.release-type != 'build-only' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: softprops/action-gh-release@v3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| body_path: ${{ github.workspace }}-CHANGELOG.txt | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| files: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ${{ env.OUTPUTS_PATCHED_OTA }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ${{ env.OUTPUTS_PATCHED_OTA }}.csig | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ${{ env.SELECTION_METADATA }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: ${{ env.GRAPHENEOS_VERSION }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| tag_name: ${{ env.GRAPHENEOS_VERSION }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish OTA metadata | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: inputs.publish && inputs.release-type != 'build-only' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shell: bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git config user.email "${{ secrets.EMAIL }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git config user.name "${{ github.repository_owner }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| current_commit="$(git rev-parse --short HEAD)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "${{ inputs.root }}" == 'true' ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| flavor='magisk' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| flavor='rootless' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| git checkout gh-pages | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| target_file="${flavor}/${DEVICE_NAME}.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant_file="variants/${ROM_FAMILY}/${flavor}/${DEVICE_NAME}-${MODULE_SELECTION_FINGERPRINT}.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mkdir -p -- "${flavor}" "$(dirname -- "${variant_file}")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| [[ -f "${DEVICE_NAME}.json" ]] || { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::Missing generated OTA metadata for ${DEVICE_NAME}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp -- "${DEVICE_NAME}.json" "${target_file}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp -- "${DEVICE_NAME}.json" "${variant_file}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git add -- "${target_file}" "${variant_file}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "${RELEASE_TYPE}" == 'force-publish' ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf 'force-publish run %s (attempt %s)\n' \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| "${GITHUB_RUN_ID}" "${GITHUB_RUN_ATTEMPT}" > .tmp | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git add -- .tmp | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+245
to
+249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🐛 Proposed fix if [[ "${RELEASE_TYPE}" == 'force-publish' ]]; then
+ marker="variants/${ROM_FAMILY}/${flavor}/.force-publish"
printf 'force-publish run %s (attempt %s)\n' \
- "${GITHUB_RUN_ID}" "${GITHUB_RUN_ATTEMPT}" > .tmp
- git add -- .tmp
+ "${GITHUB_RUN_ID}" "${GITHUB_RUN_ATTEMPT}" > "${marker}"
+ git add -- "${marker}"
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ! git diff-index --quiet HEAD; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git commit -m "release(${current_commit}): publish ${ROM_FAMILY} ${GRAPHENEOS_VERSION} ${MODULE_SELECTION_FINGERPRINT}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| git push origin gh-pages | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+250
to
+253
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win Serialize The scheduled triggers run every six hours for both ROM families, and each caller can run concurrently for different devices. Two jobs that reach line 252 at the same time produce a non-fast-forward push, and the second job fails after a full build. Add a 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,53 @@ | ||||||||||||||||||||||||||||
| name: Phase 3 build-only acceptance | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||
| rom-family: | ||||||||||||||||||||||||||||
| description: ROM family to exercise | ||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||
| type: choice | ||||||||||||||||||||||||||||
| options: | ||||||||||||||||||||||||||||
| - grapheneos | ||||||||||||||||||||||||||||
| - lineageos | ||||||||||||||||||||||||||||
| default: grapheneos | ||||||||||||||||||||||||||||
| device-id: | ||||||||||||||||||||||||||||
| description: Device code name | ||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||
| default: shiba | ||||||||||||||||||||||||||||
| root: | ||||||||||||||||||||||||||||
| description: Add root to the build | ||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||
| default: false | ||||||||||||||||||||||||||||
| magisk-preinit-device: | ||||||||||||||||||||||||||||
| description: Magisk preinit device for rooted builds | ||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||
| default: sda10 | ||||||||||||||||||||||||||||
| update-channel: | ||||||||||||||||||||||||||||
| description: Provider update channel | ||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||
| default: stable | ||||||||||||||||||||||||||||
| compatible-sepolicy-patching: | ||||||||||||||||||||||||||||
| description: Enable compatible SELinux patching | ||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||
| default: false | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||
| build-only: | ||||||||||||||||||||||||||||
| uses: ./.github/workflows/build-rom.yml | ||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win 🧩 Analysis chain🌐 Web query:
💡 Result: The error indicating that a reusable workflow cannot exceed caller permissions occurs because GitHub Actions enforces a strict security model where the calling workflow acts as a permission ceiling [1][2]. A reusable workflow cannot elevate its permissions beyond what has been explicitly granted by the job that calls it [1][2]. If a reusable workflow (the "worker") attempts to use the GITHUB_TOKEN for an action (e.g., creating a PR comment or pushing to a branch) that requires a permission level higher than what the caller provides, the workflow will fail, often resulting in a startup_failure or a specific validation error [2][3][4]. To resolve this issue, you must configure the job in the caller workflow to grant the necessary permissions [2][5]. How to Fix: 1. Identify the permissions required by your reusable workflow (e.g., contents: write, pull-requests: write) [3]. 2. In your caller workflow, add a permissions block to the specific job that calls the reusable workflow [6][2]. 3. Ensure these permissions are equal to or greater than what the reusable workflow requires [1][7]. Example of a correct caller job configuration: jobs: call-reusable-workflow: uses:./.github/workflows/my-reusable-workflow.yml permissions: contents: read pull-requests: write Key Points: - Permissions are not additive; the caller determines the maximum scope [1][2]. - If you do not specify a permissions block in the caller job, the workflow will use default permissions, which are often too restrictive for complex tasks [2][5]. - Reusable workflows can only downgrade (restrict) permissions further, never elevate them [1][2]. If you are using tools like gh-aw (GitHub Actions Workflows) or similar automation, be aware that some build systems may generate incorrect permission envelopes, and you may need to ensure your CI/CD configuration explicitly handles the union of required permissions [8][9][10]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
printf 'Files matching workflow names:\n'
fd -a '^(phase3-build-only|build-rom)\.yml$' .github/workflows || true
printf '\nRelevant workflow snippets:\n'
for f in .github/workflows/phase3-build-only.yml .github/workflows/build-rom.yml; do
if [ -f "$f" ]; then
echo "===== $f ($(wc -l < "$f") lines) ====="
sed -n '1,120p' "$f" | cat -n
fi
doneRepository: 0cwa/PixeneOS Length of output: 6402 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
caller = Path(".github/workflows/phase3-build-only.yml").read_text()
callee = Path(".github/workflows/build-rom.yml").read_text()
caller_perms = re.search(
r'^permissions:\s*\n([^\S\n]*\n(^[^\S\n]*\b[a-z-]+:(\s*.*)?\s*\n?)*)',
caller,
re.M,
)
callee_build_perms = re.search(
r'^jobs:\s*\n.*?^(build):\s*\n.*?^ permissions:\s*\n(^[^\S\n]*\b[a-z-]+:(\s*.*)?\s*\n?)',
callee,
re.M | re.S,
) if re.search(r'^jobs:', callee) else None
def get(job_perms):
if not job_perms:
return {}
return {
k.strip(): v.strip().lower()
for k, v in re.findall(r'^\s*([a-z-]+):\s*(.*?)\s*$', job_perms.group(2), re.M)
}
print("caller_perms:", get(caller_perms) if caller_perms else None)
print("build_job_permissions:", get(callee_build_perms))
print("uses_reusable_workflow:", bool(re.search(r'uses:\s*\./.github/workflows/build-rom\.yml', caller) and re.search(r'on:\s*\n\s*\n?\s*workflow_call:', callee)))
PYRepository: 0cwa/PixeneOS Length of output: 225 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf 'build-rom.yml permissions context:\n'
rg -n -C 8 '^\s*permissions:|contents:' .github/workflows/build-rom.yml
printf '\nphase3-build-only.yml permissions context:\n'
rg -n -C 8 '^\s*permissions:|contents:' .github/workflows/phase3-build-only.ymlRepository: 0cwa/PixeneOS Length of output: 1262 Grant the reusable job the permission it needs.
🐛 Proposed fix permissions:
- contents: read
+ # build-rom.yml requests contents: write for release publication.
+ contents: write📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.29.0)[warning] 42-42: secrets unconditionally inherited by called workflow (secrets-inherit): this reusable workflow (secrets-inherit) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||
| rom-family: ${{ inputs.rom-family }} | ||||||||||||||||||||||||||||
| device-id: ${{ inputs.device-id }} | ||||||||||||||||||||||||||||
| root: ${{ inputs.root }} | ||||||||||||||||||||||||||||
| magisk-preinit-device: ${{ inputs.magisk-preinit-device }} | ||||||||||||||||||||||||||||
| update-channel: ${{ inputs.update-channel }} | ||||||||||||||||||||||||||||
| compatible-sepolicy-patching: ${{ inputs.compatible-sepolicy-patching }} | ||||||||||||||||||||||||||||
| allow-unauthorized-adb: false | ||||||||||||||||||||||||||||
| release-type: build-only | ||||||||||||||||||||||||||||
| publish: false | ||||||||||||||||||||||||||||
| secrets: inherit | ||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Pin
dtolnay/rust-toolchainto a commit SHA.Line 104 references the mutable
masterbranch. This job holdsAVB_KEY,OTA_KEY, and both passphrases, and it hascontents: write. Any change pushed to that branch runs with those secrets. Pin the action to a full commit SHA.🔒 Proposed fix
🧰 Tools
🪛 zizmor (1.29.0)
[error] 104-104: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 109-109: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 109-109: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
[info] 104-104: action functionality is already included by the runner (superfluous-actions): use
rustupand/orcargoin a script step(superfluous-actions)
🤖 Prompt for AI Agents
Source: Linters/SAST tools