mirror of
https://github.com/status-im/status-app.git
synced 2026-08-31 09:01:11 +00:00
A PR can edit .gitmodules to point vendor/status-go at an arbitrary remote, letting the policy check validate against attacker-controlled refs (a fake develop branch containing any pin). Override the configured URL with the canonical upstream before 'git submodule update' in both jobs; a pin that doesn't exist upstream now fails the update, which is the correct verdict.
138 lines
5.9 KiB
YAML
138 lines
5.9 KiB
YAML
name: PR Checks
|
|
|
|
on:
|
|
pull_request:
|
|
branches:
|
|
- master
|
|
- release/**
|
|
types:
|
|
- opened
|
|
- synchronize
|
|
- reopened
|
|
- edited
|
|
|
|
jobs:
|
|
check-status-go-submodule:
|
|
name: Check status-go submodule branch
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
# head SHA, not head_ref: fork branches don't exist in this repo,
|
|
# but their commits are fetchable by SHA via the PR ref network
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
fetch-depth: 0
|
|
submodules: false
|
|
|
|
- name: Get status-go submodule commit
|
|
id: statusgo
|
|
run: |
|
|
commit=$(git ls-tree HEAD vendor/status-go | awk '{print $3}')
|
|
echo "commit=$commit" >> $GITHUB_OUTPUT
|
|
echo "[LOG] status-go submodule commit: $commit"
|
|
|
|
- name: Fetch relevant status-go branches
|
|
run: |
|
|
# pin the submodule URL so a PR-modified .gitmodules cannot point
|
|
# the policy check at a non-upstream remote
|
|
git submodule init vendor/status-go
|
|
git config submodule.vendor/status-go.url https://github.com/status-im/status-go.git
|
|
git submodule update vendor/status-go
|
|
cd vendor/status-go
|
|
if ! git fetch origin 'release/*:refs/remotes/origin/release/*' 2>/dev/null; then
|
|
echo "[WARN] No release/* branches found."
|
|
fi
|
|
if ! git fetch origin develop:refs/remotes/origin/develop 2>/dev/null; then
|
|
echo "[WARN] develop branch not found on remote."
|
|
fi
|
|
echo "[LOG] status-go relevant branches fetched."
|
|
|
|
- name: Get containing branches
|
|
id: branches
|
|
run: |
|
|
cd vendor/status-go
|
|
branches=$(git branch -r --contains ${{ steps.statusgo.outputs.commit }} | sed 's/ *origin\///')
|
|
# Normalize branch list: remove 'HEAD -> ...', trim whitespace, one per line
|
|
cleaned_branches=$(echo "$branches" | sed '/HEAD ->/d' | awk '{$1=$1};1')
|
|
echo "branches<<EOF" >> $GITHUB_OUTPUT
|
|
echo "$cleaned_branches" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
echo "[LOG] status-go commit is contained in branches:"
|
|
echo "$cleaned_branches"
|
|
|
|
- name: Fetch base branch status-go commit
|
|
run: |
|
|
git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
|
|
BASE_STATUS_GO_COMMIT=$(git ls-tree ${{ github.base_ref }} vendor/status-go | awk '{print $3}')
|
|
echo "BASE_STATUS_GO_COMMIT=$BASE_STATUS_GO_COMMIT" >> $GITHUB_ENV
|
|
echo "[LOG] status-go commit on base branch (${{ github.base_ref }}): $BASE_STATUS_GO_COMMIT"
|
|
|
|
- name: Check if status-go submodule changed
|
|
id: check_statusgo_changed
|
|
run: |
|
|
git fetch origin ${{ github.base_ref }}
|
|
if git diff --name-only origin/${{ github.base_ref }} HEAD | grep -q '^vendor/status-go$'; then
|
|
echo "changed=true" >> $GITHUB_OUTPUT
|
|
echo "[LOG] status-go submodule changed in this PR."
|
|
else
|
|
echo "changed=false" >> $GITHUB_OUTPUT
|
|
echo "[LOG] status-go submodule NOT changed in this PR."
|
|
fi
|
|
|
|
- name: Validate status-go branch policy for master
|
|
if: steps.check_statusgo_changed.outputs.changed == 'true' && github.base_ref == 'master'
|
|
run: |
|
|
BRANCHES="${{ steps.branches.outputs.branches }}"
|
|
echo "[LOG] Checking branch policy for master branch"
|
|
if ! echo "$BRANCHES" | grep -x 'develop'; then
|
|
echo "::error::status-go submodule must point to a commit on 'develop' branch when PR targets master."
|
|
exit 1
|
|
fi
|
|
echo "[LOG] status-go commit is on develop branch."
|
|
|
|
- name: Validate status-go branch policy for release
|
|
if: steps.check_statusgo_changed.outputs.changed == 'true' && startsWith(github.base_ref, 'release/')
|
|
run: |
|
|
BRANCHES="${{ steps.branches.outputs.branches }}"
|
|
echo "[LOG] Checking branch policy for release branch: ${{ github.base_ref }}"
|
|
if ! echo "$BRANCHES" | grep -E '^release/' >/dev/null; then
|
|
echo "::error::status-go submodule must point to a commit on a 'release/*' branch when PR targets a release branch."
|
|
exit 1
|
|
fi
|
|
echo "[LOG] status-go commit is on a release/* branch."
|
|
|
|
- name: Validate status-go commit recency
|
|
if: steps.check_statusgo_changed.outputs.changed == 'true'
|
|
run: |
|
|
STATUS_GO_COMMIT="${{ steps.statusgo.outputs.commit }}"
|
|
BASE_STATUS_GO_COMMIT="$BASE_STATUS_GO_COMMIT"
|
|
echo "[LOG] Checking commit recency: PR=$STATUS_GO_COMMIT, base=$BASE_STATUS_GO_COMMIT"
|
|
cd vendor/status-go
|
|
if git merge-base --is-ancestor "$BASE_STATUS_GO_COMMIT" "$STATUS_GO_COMMIT"; then
|
|
echo "[LOG] status-go commit is newer than or equal to base branch. OK."
|
|
else
|
|
echo "::error::status-go submodule commit in PR is older than the one on the base branch."
|
|
exit 1
|
|
fi
|
|
wakuext-binding-contract:
|
|
name: wakuext FFI binding contract
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
# default (merge) ref on purpose: the contract must hold on the result of
|
|
# merging the PR, not on the PR's possibly-stale vendor pin
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
submodules: false
|
|
- name: Init vendored status-go (the shipped pin)
|
|
run: |
|
|
# same URL pinning as above: never fetch a PR-supplied remote
|
|
git submodule init vendor/status-go
|
|
git config submodule.vendor/status-go.url https://github.com/status-im/status-go.git
|
|
git submodule update vendor/status-go
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.11"
|
|
- run: pip install pytest==8.4.1
|
|
- name: Run the binding contract
|
|
run: python -m pytest test/contract/test_wakuext_binding.py -v
|