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
79 changes: 79 additions & 0 deletions .github/check-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/sh
#
# check-version.sh — fail a pull request that changes the app or its build
# but not versionName in android/app/build.gradle. A new version must be
# MAJOR.MINOR.PATCH without leading zeros, greater than the base one, and
# have its section in CHANGELOG.md ("## <version> — YYYY-MM-DD") that the
# base branch does not have yet. android/ counts as app or build (its unit
# tests in android/app/src/test do not); docs, screenshots and the
# workflows in .github/ need no new version. The format is checked only
# when the version changes, so the 2.xx versions before MAJOR.MINOR.PATCH
# stay valid until the next app change.
#
# Usage: .github/check-version.sh [BASE] (default origin/v2; CI passes
# HEAD^1, the base side of the pull request's merge commit)
#

set -eu

base=${1:-origin/v2}
gradle=android/app/build.gradle
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.

# The one versionName assignment (comments and other text do not count).
ver() {
v=$(sed -n 's/^[[:space:]]*versionName[[:space:]]*"\([^"]*\)"[[:space:]]*$/\1/p')
if [ "$(printf '%s\n' "$v" | grep -c .)" -ne 1 ]; then
echo "::error::$1:$gradle: expected one versionName assignment," \
"found: $(printf '%s' "$v" | tr '\n' ' ')" >&2
exit 1
fi
printf '%s\n' "$v"
}

new=$(ver HEAD < "$gradle")
old=$(git show "$base:$gradle" | ver "$base")

changed=$(git diff --name-only "$base"...HEAD -- android ':(exclude)android/app/src/test')

if [ "$new" = "$old" ]; then
if [ -n "$changed" ]; then
echo "::error::the app or its build changed, versionName is still $old:" \
"bump PATCH (fix) or MINOR (feature) and add its CHANGELOG.md section"
echo "$changed"
exit 1
fi
echo "version $new unchanged, no app or build changes"
exit 0
fi

if ! echo "$new" | grep -Eq '^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then
echo "::error::versionName \"$new\" is not MAJOR.MINOR.PATCH"
exit 1
fi

# A 2.xx version from before MAJOR.MINOR.PATCH is X.Y.0: 2.17.0 is 2.17.
case $old in
*.*.*) oldn=$old ;;
*) oldn=$old.0 ;;
esac
top=$(printf '%s\n%s\n' "$oldn" "$new" | sort -V | tail -n 1)
if [ "$new" = "$oldn" ] || [ "$top" != "$new" ]; then
echo "::error::versionName $new is not greater than $old"
exit 1
fi

# $new is digits and dots only (checked above): escape the dots, require a date.
re=$(printf '%s' "$new" | sed 's/\./\\./g')
if ! grep -Eq "^## $re — [0-9]{4}-[0-9]{2}-[0-9]{2}\$" CHANGELOG.md; then
echo "::error::CHANGELOG.md has no section \"## $new — YYYY-MM-DD\""
exit 1
fi

# The section must come with this pull request, not be one the base
# branch already has (a version taken from there brings no notes).
if git show "$base:CHANGELOG.md" 2>/dev/null | grep -Eq "^## $re — "; then
echo "::error::the section \"## $new\" is already on $base: take a new version"
exit 1
fi

echo "version $old -> $new, CHANGELOG.md section found"
17 changes: 17 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ concurrency:
cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }}

jobs:
# Pull requests: a change to the app or its build comes with a new versionName
# (MAJOR.MINOR.PATCH) and its CHANGELOG.md section (.github/check-version.sh, #230)
version:
# basic keeps its own workflow and version file (app/build.gradle)
if: github.event_name == 'pull_request' && github.base_ref == 'v2'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Retargeted pull requests skip version checks 🐞 Bug ≡ Correctness

The new version job is conditional on github.base_ref == 'v2', but the workflow uses the default
pull-request activity types, which do not include edited. If an existing pull request is
retargeted from another branch to v2, the base-branch edit does not run the job, so its current
app changes remain unchecked until another qualifying event occurs.
Agent Prompt
## Issue description
Retargeting a pull request to v2 does not trigger the version check because the workflow does not subscribe to pull-request edits.

## Fix Focus Areas
- .github/workflows/build.yml[1-5]
- .github/workflows/build.yml[23-36]

## Recommended Fix
Specify pull_request activity types that include edited alongside opened, synchronize, and reopened, so retargeting reruns the base-dependent version job.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

# The checkout is the pull request's merge commit: its first parent is the
# base it was made from, so both versions come from the same base.
- name: App changes come with a new version
run: .github/check-version.sh HEAD^1

# Unit tests and lint; also runs for pull requests from forks (no secrets needed)
test:
runs-on: ubuntu-latest
Expand Down
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ newest `v2` and `basic` builds, and in the OpenIPC Telegram channel; there are n
per version (#194). This file is the change history: one section per `v2` version, newest
first, then the legacy `basic` line.

Versions after 2.17 are `MAJOR.MINOR.PATCH` (2.17 is followed by 2.17.1 or 2.18.0; see
`docs/testing.md`, "Versions and releases"); the headings below keep the numbers as they
were released.

## 2.17 — 2026-10-17

- Turn in the camera settings (Auto, 0°, 90°, 180°, 270°), stored per slot; H.264/H.265 are
Expand Down Expand Up @@ -108,10 +112,10 @@ Versions 1.x of the `v2` line, up to 1.28 (2026-05-04) and the work merged until

`basic` is the original app, `decoder.apk` in the `latest` release; it gets fixes only.

### 1.07.1 — 2026-10-12
### 1.7.1 — 2026-10-12

- Robust RTSP handshake, end-of-stream handling, thread lifecycle and SDP parsing (PR #41,
#36–#40).
- Released as 1.07.1 (written 1.7.1 since #230). Robust RTSP handshake, end-of-stream
handling, thread lifecycle and SDP parsing (PR #41, #36–#40).
Comment on lines +115 to +118

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Historical release notes rename 1.07.1 📎 Requirement gap ⚙ Maintainability

CHANGELOG.md replaces the historical 1.07.1 heading with 1.7.1 while rewriting its entry text.
Readers scanning headings see a number other than the published version, even though the
introduction says headings retain released numbers and the entry text identifies the release as
1.07.1.
Agent Prompt
## Issue description
The historical `1.07.1` changelog heading was changed to its canonical `1.7.1` spelling, contradicting the introduction's statement that headings retain released numbers.

## Fix Focus Areas
- CHANGELOG.md[10-12]
- CHANGELOG.md[115-118]

## Recommended Fix
Restore the heading to `### 1.07.1 — 2026-10-12`. Keep the explanation of the canonical `1.7.1` spelling in the entry text or changelog introduction without renaming the released heading.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


### 1.07 — 2025-11-11

Expand Down
4 changes: 2 additions & 2 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ CI is the reference: the project does not depend on local builds.

## Versions and releases

- `v2` is **2.xx** (from 2.00). Every pull request that changes the app bumps `android/app/build.gradle` as its last commit before the merge: `versionName` +0.01, `versionCode` +1. Docs-only and CI-only pull requests do not.
- `basic` keeps its 1.07.x line.
- Versions are **`MAJOR.MINOR.PATCH`** (`versionName` in `android/app/build.gradle`): PATCH for fixes and small changes, MINOR for a new feature, MAJOR for an incompatible change or a large update, only when the maintainer decides. Every pull request that changes the app or its build (`android/`, except the unit tests) bumps the version as its last commit before the merge: `versionName` by that rule and `versionCode` +1. Docs-only, test-only and CI-only pull requests do not. Numbers are not reserved for open pull requests: each one takes the next number when it is merged. CI checks this on every pull request (`.github/check-version.sh`): a new number must be canonical (no leading zeros), greater than the base one, and come with its own `CHANGELOG.md` section.
- Until 2.17 `v2` counted **2.xx** (+0.01 per pull request); 2.17 is followed by 2.17.1 or 2.18.0. `basic` keeps its 1.7.x line (1.07.1 is 1.7.1).
- **`CHANGELOG.md`** is the change history: the version bump commit of a pull request that changes the app adds the version's section (`## <version> — <date>`, newest first) in the same pull request.
- Development is continuous, so there is **no release per version** (#194). The [`latest`](https://github.com/OpenIPC/decoder/releases/tag/latest) release always holds the newest `v2` and `basic` builds. Every `v2` and `basic` build is also posted to the OpenIPC Telegram channel with its version and commit, and that is where their older builds can be found. Builds of other branches are only workflow artifacts of their runs (90 days).
- **Test pre-releases**: to let a reporter test a branch, a pre-release named after the issue is made by hand from the branch's CI artifact, e.g. [`toys-187-test2`](https://github.com/OpenIPC/decoder/releases/tag/toys-187-test2) for #187. It is deleted when the test is over, or replaced by the next one.
Expand Down
Loading