Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions .github/workflows/xposed-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: xposed-release

# Mirrors a release from this (source) repo into the module's entry in the
# Xposed Modules Repository, which is what LSPosed's module browser actually
# reads from: https://github.com/Xposed-Modules-Repo/com.xiddoc.playintegrityalert
#
# The Xposed repo requires each release's TAG to be "<versionCode>-<versionName>"
# (e.g. 123-1.0.0) and to carry the APK as an asset. Our own releases keep their
# human-friendly "v1.0.0" tags; this job re-tags the mirror to the required shape,
# uploads the same APK, and syncs the entry's README/SUMMARY/SOURCE_URL from the
# xposed-repo/ folder in this repo — so the entry is maintained entirely from here.
#
# Setup (one time):
# 1. The entry repo already exists at Xposed-Modules-Repo/com.xiddoc.playintegrityalert
# with you as a collaborator. Make sure its repo *description* is the module's
# display name ("Play Integrity Alert") — set in the entry repo's settings.
# 2. Create a CLASSIC PAT (github.com → Settings → Developer settings → Tokens
# (classic)) with the `public_repo` scope, and add it to THIS repo as the secret
# XPOSED_REPO_TOKEN (Settings → Secrets and variables → Actions).
# - The secret lives in THIS repo (where the workflow runs), NOT in the entry
# repo — so you don't need any secret access on Xposed-Modules-Repo.
# - It must be a CLASSIC token, not fine-grained: a classic PAT inherits your
# own access, which includes your collaborator write access to the entry
# repo. A fine-grained PAT can't target an org repo you only collaborate on.
# After that, every published release here is mirrored automatically. You can also
# re-run it by hand (workflow_dispatch) to repair the entry or push metadata-only
# edits against an existing release.

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Source release tag to mirror (default: latest release)"
required: false

concurrency:
group: xposed-release
cancel-in-progress: false

env:
# The entry repo — its NAME must equal the module's package name.
XPOSED_REPO: Xposed-Modules-Repo/com.xiddoc.playintegrityalert

jobs:
mirror:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Full history + tags: the versionCode is the commit count at the tag,
# exactly as release.yml computes it when building the APK.
fetch-depth: 0

- name: Resolve the source release tag
id: src
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
tag="${{ github.event.release.tag_name || inputs.tag }}"
if [ -z "$tag" ]; then
tag="$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName -q .tagName)"
fi
echo "Mirroring source release: $tag"
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Derive the Xposed tag (VersionCode-VersionName)
id: xtag
run: |
set -euo pipefail
tag="${{ steps.src.outputs.tag }}"
name="${tag#v}" # v1.0.0 -> 1.0.0 (leaves bare names as-is)
git fetch --tags --force origin
# versionCode == commit count at the tagged commit; matches the APK, which
# release.yml builds with -PVERSION_CODE="$(git rev-list --count HEAD)".
code="$(git rev-list --count "$tag")"
xtag="${code}-${name}"
echo "Xposed tag: $xtag"
echo "name=$name" >> "$GITHUB_OUTPUT"
echo "xtag=$xtag" >> "$GITHUB_OUTPUT"

- name: Download the source release APK
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p dist
gh release download "${{ steps.src.outputs.tag }}" \
--repo "$GITHUB_REPOSITORY" \
--pattern '*.apk' \
--dir dist
ls -la dist

- name: Sync entry metadata (README, SUMMARY, SOURCE_URL)
env:
GH_TOKEN: ${{ secrets.XPOSED_REPO_TOKEN }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "::error::XPOSED_REPO_TOKEN is not set — cannot push to $XPOSED_REPO. See this workflow's header for setup."
exit 1
fi
tmp="$(mktemp -d)"
git clone "https://x-access-token:${GH_TOKEN}@github.com/${XPOSED_REPO}.git" "$tmp"
cp xposed-repo/README.md "$tmp/README.md"
cp xposed-repo/SUMMARY "$tmp/SUMMARY"
cp xposed-repo/SOURCE_URL "$tmp/SOURCE_URL"
cd "$tmp"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "Entry metadata already up to date."
else
git commit -m "Sync entry metadata for ${{ steps.src.outputs.tag }}"
git push
fi

- name: Publish the mirror release to the Xposed repo
env:
GH_TOKEN: ${{ secrets.XPOSED_REPO_TOKEN }}
run: |
set -euo pipefail
xtag="${{ steps.xtag.outputs.xtag }}"
notes="Play Integrity Alert ${{ steps.src.outputs.tag }} — mirrored from ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${{ steps.src.outputs.tag }}"
if gh release view "$xtag" --repo "$XPOSED_REPO" >/dev/null 2>&1; then
echo "Release $xtag already exists on $XPOSED_REPO — refreshing its APK asset."
gh release upload "$xtag" dist/*.apk --repo "$XPOSED_REPO" --clobber
else
gh release create "$xtag" dist/*.apk \
--repo "$XPOSED_REPO" \
--title "$xtag" \
--notes "$notes"
fi
echo "Published $xtag to $XPOSED_REPO"
45 changes: 45 additions & 0 deletions xposed-repo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<p align="center">
<img src="https://raw.githubusercontent.com/Xiddoc/PlayIntegrityAlert/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" width="120" alt="Play Integrity Alert">
</p>

<h1 align="center">Play Integrity Alert</h1>

<p align="center">
<a href="https://github.com/Xposed-Modules-Repo/com.xiddoc.playintegrityalert/releases/latest"><img src="https://img.shields.io/github/v/release/Xposed-Modules-Repo/com.xiddoc.playintegrityalert?label=release" alt="Latest release"></a>
<a href="https://github.com/Xposed-Modules-Repo/com.xiddoc.playintegrityalert/releases"><img src="https://img.shields.io/github/downloads/Xposed-Modules-Repo/com.xiddoc.playintegrityalert/total?label=downloads" alt="Downloads"></a>
<a href="https://github.com/Xiddoc/PlayIntegrityAlert"><img src="https://img.shields.io/github/stars/Xiddoc/PlayIntegrityAlert?label=source%20stars" alt="Source stars"></a>
<a href="https://github.com/Xiddoc/PlayIntegrityAlert/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Xiddoc/PlayIntegrityAlert" alt="License"></a>
</p>

## About this module

**Play Integrity Alert notifies you the moment an app asks for a Google Play
Integrity verdict.**

Scope the module to Google Play Store, choose which apps you care about (or watch
them all), and whenever one of them calls the Play Integrity API you get a
notification — with the app's name — plus an in-app history of every detection.

The Play Integrity client libraries don't compute a verdict in-process; they hand
the request to **Google Play Store** (`com.android.vending`, "Finsky"), and the
caller's package travels *inside* that request. So the module injects into the
**Play Store process only** and observes the integrity requests as they arrive —
it never alters the verdict, it only tells you it happened.

This module behaves just like the
[GrapheneOS Play Integrity alert](https://x.com/GrapheneOS/status/1877790719009529972)
feature, and is inspired by it.

## Usage

1. Install the APK and **enable Play Integrity Alert** in LSPosed.
2. Open the module's **Scope** and tick **Google Play Store** (`com.android.vending`)
— that's the only app you need. It's a system app, so if you don't see it, enable
**Show system apps** from the scope screen's ⋮ menu and refresh.
3. **Restart Play Store** so the hook loads (the app has a button for this; with root
it's automatic).

## Source & documentation

Full source, build instructions, and issue tracker live in the upstream repository:
**https://github.com/Xiddoc/PlayIntegrityAlert**
1 change: 1 addition & 0 deletions xposed-repo/SOURCE_URL
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/Xiddoc/PlayIntegrityAlert
1 change: 1 addition & 0 deletions xposed-repo/SUMMARY
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Notifies you whenever an app requests a Google Play Integrity verdict. Scope it to Google Play Store.
Loading