Automated pipeline for tracking Android build properties and compiling validated Play Integrity Fix (PIF) JSON profiles.
Upstream Repositories
├── Pixel-Props/build.prop (Stable)
└── Elcapitanoe/Build-Prop-BETA (Beta)
│
▼
[ pif-gen check ] ─── Poll tags vs local state/
│
▼ (On tag update)
[ pif-gen build ] ─── Download ZIPs ──> Extract system.prop ──> Parse & Validate
│
▼
[ pif-gen publish ] ─ Deploy unified release bundle (vYYYY.MM.DD)
Properties are resolved across partition namespaces (system_ext > system > product > vendor) and validated against Pydantic schemas.
| Key | Property Resolution Order | Description |
|---|---|---|
ID |
ro.system_ext.build.id → ro.system.build.id → ro.build.id → ro.vendor.build.id |
Android build identifier |
BRAND |
ro.product.system_ext.brand → ro.product.system.brand → ro.product.brand |
Device brand (google) |
DEVICE |
ro.product.system_ext.device → ro.product.system.device → ro.product.device |
Hardware board codename |
MANUFACTURER |
ro.product.system_ext.manufacturer → ro.product.manufacturer |
Hardware manufacturer |
MODEL |
ro.product.system_ext.model → ro.product.system.model → ro.product.model |
Commercial model name |
PRODUCT |
ro.product.system_ext.name → ro.product.system.name → ro.product.name |
Product codename |
FINGERPRINT |
ro.system_ext.build.fingerprint → ro.build.fingerprint → ro.vendor.build.fingerprint |
Build fingerprint |
SECURITY_PATCH |
ro.build.version.security_patch → parsed date pattern |
Patch date (YYYY-MM-DD) |
DEVICE_INITIAL_SDK_INT |
ro.product.first_api_level → ro.board.first_api_level → ro.system.build.version.sdk |
Factory launch SDK |
RELEASE |
ro.system_ext.build.version.release → ro.build.version.release |
Android OS version |
TYPE |
ro.system_ext.build.type → ro.build.type |
Build type (user) |
TAG |
ro.system_ext.build.tags → ro.build.tags |
Signing key tag (release-keys) |
DEBUG |
Evaluated (ro.debuggable == 1 or TYPE != user) |
Debug build flag (false) |
{
"ID": "CP41.260814.003.B1",
"BRAND": "google",
"DEVICE": "komodo",
"MANUFACTURER": "Google",
"FINGERPRINT": "google/komodo_beta/komodo:17/CP41.260814.003.B1/16166531:user/release-keys",
"MODEL": "Pixel 9 Pro XL",
"PRODUCT": "komodo_beta",
"SECURITY_PATCH": "2026-08-14",
"DEVICE_INITIAL_SDK_INT": "34",
"TYPE": "user",
"TAG": "release-keys",
"RELEASE": "17",
"DEBUG": false,
"spoofBuild": "1",
"spoofProps": "0",
"spoofProvider": "0",
"spoofSignature": "0",
"spoofVendingSdk": "0",
"verboseLogs": "0"
}Install Python 3.10+, pip, and git:
Ubuntu / Debian / WSL:
sudo apt update && sudo apt install -y python3 python3-pip python3-venv gitFedora / RHEL:
sudo dnf install -y python3 python3-pip gitArch Linux:
sudo pacman -S --needed python python-pip gitmacOS (Homebrew):
brew install python gitWindows: Install Python 3.10+ via python.org or winget:
winget install Python.Python.3.12 Git.Git# 1. Clone the repository
git clone https://github.com/Elcapitanoe/pif-config-generator.git
cd pif-config-generator
# 2. Create and activate an isolated virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Upgrade pip and install package in editable mode with dev tools
pip install --upgrade pip
pip install -e ".[dev]"Verify the installation:
pif-gen --helpGenerate a validated PIF JSON profile from a local system.prop or property dump. No network access or GitHub token required.
pif-gen build --file path/to/system.prop --output-dir outputOr extract directly from a remote ZIP URL:
pif-gen build --url "https://github.com/.../device.zip" --output-dir outputOptions:
--file <path>: Path to the input property dump file.--url <url>: Direct URL to an upstream property ZIP archive.--output-dir <dir>: Destination directory for the generated JSON file (defaults to current directory.).--format <extended|legacy>: Profile schema to target (extendedfor modern modules,legacyfor older modules; default:extended).--channel <stable|beta>: Target release channel label (default:stable).
To dump build properties directly from a connected Android device:
adb shell getprop | sed -r 's/\[(.*)\]: \[(.*)\]/\1=\2/' > system.prop
pif-gen build --file system.prop --output-dir outputro.system_ext.build.id=CP41.260814.003.B1
ro.product.system_ext.brand=google
ro.product.system_ext.device=komodo
ro.product.system_ext.manufacturer=Google
ro.product.system_ext.model=Pixel 9 Pro XL
ro.product.system_ext.name=komodo_beta
ro.system_ext.build.fingerprint=google/komodo_beta/komodo:17/CP41.260814.003.B1/16166531:user/release-keys
ro.build.version.security_patch=2026-08-14
ro.product.first_api_level=34
ro.system_ext.build.version.release=17
ro.system_ext.build.type=user
ro.system_ext.build.tags=release-keys
ro.debuggable=0Poll monitored upstream repositories (Pixel-Props/build.prop for stable, Elcapitanoe/Build-Prop-BETA for beta) and compare latest releases against local tracking tags in state/last_<channel>_tag.txt.
Works unauthenticated for checking public releases (subject to standard GitHub API rate limits), or authenticated via personal access token:
# Optional: Set token to avoid rate limits
export GITHUB_TOKEN="ghp_xxx"
pif-gen check --state-dir stateOptions:
--state-dir <dir>: Directory storing release tag state files (default:state).--token <token>: GitHub personal access token (falls back to theGITHUB_TOKENenvironment variable).
Sample output:
{
"new_release": true,
"results": [
{
"channel": "beta",
"tag": "2026.08.14",
"assets": [
{
"name": "Komodo_beta.zip",
"url": "https://github.com/.../Komodo_beta.zip"
}
],
"count": 1
}
]
}Download property ZIP archives from URLs, extract system.prop in memory, validate against the Pydantic schema, write JSON files to disk, and write a manifest list of generated paths:
pif-gen build \
--channel beta \
--assets-json '[{"name": "Komodo_beta.zip", "url": "https://github.com/.../Komodo_beta.zip"}]' \
--output-dir output \
--manifest output/manifest.txtOptions:
--channel <stable|beta>: Target release channel for the asset payloads.--assets-json <json>: JSON array of{ "name": "...", "url": "..." }asset descriptors.--output-dir <dir>: Output directory for generated JSON files.--manifest <path>: Output text file tracking generated profile paths.
Upload generated profiles from a manifest file to GitHub Releases on the target repository using unified daily version tags (vYYYY.MM.DD):
export GITHUB_TOKEN="ghp_xxx"
pif-gen publish \
--repo "owner/repo" \
--manifest output/manifest.txtOptions:
--repo <owner/repo>: Target GitHub repository.--manifest <path>: Path to the manifest file containing paths of files to upload.--token <token>: GitHub personal access token (falls back toGITHUB_TOKEN).
Run the test suite using pytest:
pytest tests/ -vOr using the standard library test runner:
python3 -m unittest discover tests -v