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
2 changes: 1 addition & 1 deletion .github/workflows/build-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
run: python scripts/add_strings.py --check

# These scripts gate other checks - add_strings.py gates the step above, and
# exporter_version.py gates the exporter release - so a bug in one of them reports
# release_version.py gates the exporter and Android releases - so a bug in one of them reports
# green while protecting nothing.
- name: Test the tooling in scripts/
run: |
Expand Down
39 changes: 16 additions & 23 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,25 @@ jobs:
&& startsWith(github.event.release.tag_name, 'android-app-v')

steps:
- name: Extract Version from Tag
id: extract_version
run: |
# GITHUB_REF for tags is like 'refs/tags/android-app-v1.0.3.1'
FULL_TAG_NAME="${{ github.ref }}"

# Remove 'refs/tags/' prefix to get 'android-app-v1.0.3.1'
TAG_WITHOUT_PREFIX="${FULL_TAG_NAME##refs/tags/}"

# Find the index of '-v'
# This will be 'android-app-' part, then we add 2 to skip '-v'
START_INDEX=$(( $(echo "$TAG_WITHOUT_PREFIX" | awk -F'-v' '{print length($1)}') + 2 ))

# Extract everything from '-v' onwards
# Using cut or substring if available, or just awk
VERSION_STRING=$(echo "$TAG_WITHOUT_PREFIX" | cut -c "$START_INDEX"-)

# Output the extracted version as a step output
echo "Extracted version: $VERSION_STRING"

# !! this is reused below
echo "APP_VERSION=$VERSION_STRING" >> $GITHUB_OUTPUT

- name: Checkout code
uses: actions/checkout@v4

# Nothing rewrites versionName from the tag: it is what the app reports about itself in
# Settings and in bug reports, and it is baked into the APK. So a tag that disagrees
# with app/build.gradle.kts publishes an APK calling itself the old version, under a
# release page claiming the new one, and nothing anywhere says so.
#
# This replaces parsing the tag by hand. The version now comes from the source and the
# tag only has to agree with it, which is the same arrangement the macOS exporter has
# used since scripts/release_version.py was introduced. It runs before the Gradle build,
# so a mismatch costs seconds rather than a full signed build.
- name: Check the release tag matches the version in the source
id: extract_version
run: |
APP_VERSION="$(python3 scripts/release_version.py --kind android --tag "${{ github.ref }}")"
echo "Tag and source agree on version: $APP_VERSION"
echo "APP_VERSION=$APP_VERSION" >> $GITHUB_OUTPUT

# Set Current Date As Env Variable
- name: Set current date as env variable
run: echo "date_today=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/macos-exporter-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ jobs:
# a mismatch costs one minute rather than two full PyInstaller builds.
#
# Deliberately not the reverse - patching the tag into the source - because the wizard
# also runs from source, and those exports stamp `via:` too. See scripts/exporter_version.py.
# also runs from source, and those exports stamp `via:` too. See scripts/release_version.py.
- name: Check the release tag matches the version in the source
id: version
run: |
APP_VERSION="$(python3 scripts/exporter_version.py --tag "${{ github.ref }}")"
APP_VERSION="$(python3 scripts/release_version.py --kind exporter --tag "${{ github.ref }}")"
echo "Tag and source agree on version: $APP_VERSION"
echo "APP_VERSION=$APP_VERSION" >> $GITHUB_OUTPUT

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macos-scripts-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ jobs:
- name: Check the exporter version is still readable
working-directory: .
run: |
python scripts/exporter_version.py --print
python scripts/release_version.py --kind exporter --print
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ So releasing is two steps, in this order:
1. Commit the `VERSION` bump to `main`
2. Tag that commit `macos-exporter-v<the same version>` and publish the release

`scripts/exporter_version.py --tag <tag>` enforces it, and runs in `test-release-version`
`scripts/release_version.py --kind exporter --tag <tag>` enforces it, and runs in `test-release-version`
before either build job. A tag that disagrees fails the release rather than shipping a build
that lies about itself. Full procedure: [CONTRIBUTING.md](./CONTRIBUTING.md#releasing-the-macos-exporter).

Expand Down
47 changes: 44 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ The tag must be `macos-exporter-v` followed by exactly what `VERSION` says. Befo
build job starts, `test-release-version` runs:

```bash
python scripts/exporter_version.py --tag macos-exporter-v1.0.6
python scripts/release_version.py --kind exporter --tag macos-exporter-v1.0.6
```

which fails the release, with instructions, if the two disagree — so the mistake costs a
Expand All @@ -468,14 +468,55 @@ name, the release title, and the version the app reports cannot come apart.
You can run the same check locally before tagging:

```bash
python scripts/exporter_version.py --print # what the source declares
python scripts/exporter_version.py --tag macos-exporter-v1.0.6 # would this tag be accepted?
python scripts/release_version.py --kind exporter --print # what the source declares
python scripts/release_version.py --kind exporter --tag macos-exporter-v1.0.6 # would this tag be accepted?
```

If you tagged before bumping, the fix is to push the bump, delete the release and its tag, and
re-tag the new commit. Releasing the Android app is unrelated and unaffected — its version
lives in `app/build.gradle.kts`.

## Releasing the Android app

Same shape as the exporter, with the version in a different file — `versionName` in
`app/build.gradle.kts`:

```kotlin
versionCode = 3
versionName = "1.0.5"
```

**Bump `versionCode` too.** Android refuses to install an APK whose code is not higher than
the installed one, so a `versionName`-only bump leaves existing users unable to update — and
it fails on their phone, never in any build.

```bash
# 1. Bump both, commit, push
git commit -am "Bump the Android app to 1.0.6"
git push origin main

# 2. Draft the release, then publish it from the GitHub UI
python scripts/release_notes.py draft --kind android --changes-file notes.md

# 3. Collapse the release it replaced
python scripts/release_notes.py demote --kind android
```

Publishing runs `build-release.yml`, which checks the tag against the source before building
anything:

```bash
python scripts/release_version.py --kind android --tag android-app-v1.0.6
```

then runs the tests, builds and signs the APK, and attaches it to the release. The tag must be
`android-app-v` followed by exactly what `versionName` says; the check fails the release, with
instructions, if they disagree.

Signing needs `SIGNING_KEY`, `KEY_STORE_PASSWORD`, `KEY_PASSWORD` and the `ALIAS` in the
**Android Build Release** environment. Those are separate from the exporter's token, and a
release is a bad time to discover one has expired.

## Opening a pull request

- Run `./gradlew testAll` and `python scripts/add_strings.py --check` first
Expand Down
6 changes: 3 additions & 3 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ Zip up result (MacOS):
```shell
# Read from the source rather than typed, so the zip cannot end up named after a version the
# app does not report. See "Versioning" below.
APP_VERSION="$(python ../scripts/exporter_version.py --print)"
APP_VERSION="$(python ../scripts/release_version.py --kind exporter --print)"
cd ./dist
zip -r OpenTagViewer-ExportWizardMacOS-$APP_VERSION.zip OpenTagViewer.app/ OpenTagViewer
```
Expand All @@ -169,8 +169,8 @@ Releases are tagged `macos-exporter-v<version>`, and CI refuses to publish one w
disagrees with the source:

```shell
python ../scripts/exporter_version.py --print # what the source declares
python ../scripts/exporter_version.py --tag macos-exporter-v1.0.6 # would this tag be accepted?
python ../scripts/release_version.py --kind exporter --print # what the source declares
python ../scripts/release_version.py --kind exporter --tag macos-exporter-v1.0.6 # would this tag be accepted?
```

Not to be confused with `EXPORT_METADATA_VERSION`, a few lines below it: that is the version
Expand Down
2 changes: 1 addition & 1 deletion python/main/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
# The single source of truth for the exporter's version: it appears in the window title and
# is stamped into every export as `via: OpenTagViewer.app:<version>`. Releases are tagged
# macos-exporter-v<this>, and CI refuses to publish a release whose tag disagrees - see
# scripts/exporter_version.py and CONTRIBUTING.md -> Releasing the macOS exporter.
# scripts/release_version.py and CONTRIBUTING.md -> Releasing the macOS exporter.
VERSION = "1.0.5"

APP_TITLE = f"OpenTagViewer AirTag Exporter {VERSION}"
Expand Down
Loading
Loading