Add longer location-sharing intervals (10 min … 2 h) #54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [master] | |
| tags: ["v*"] | |
| pull_request: | |
| workflow_dispatch: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| # Least-privilege default for GITHUB_TOKEN; the release-apk job opts up to | |
| # `contents: write` for creating the GitHub Release. Without this, jobs would | |
| # inherit the repository default, which may grant an unnecessary write token. | |
| permissions: | |
| contents: read | |
| # Cancel superseded runs for the same PR; never cancel master or tag builds. | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # Compile + unit tests + lint. Runs on every push to master, every PR, and | |
| # every tag (it gates the APK jobs below via `needs`). | |
| test: | |
| name: Test & lint (host) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| # Pinned by SHA, so the @stable ref no longer selects the channel; | |
| # name it explicitly. | |
| toolchain: stable | |
| components: clippy, rustfmt | |
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Install system dependencies | |
| # Slint's core text layout (parley -> fontique) links fontconfig on | |
| # Linux, so even a host `cargo test` of the GUI crate needs its dev | |
| # package; the build script shells out to pkg-config for fontconfig.pc. | |
| run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev | |
| - name: Tests | |
| run: cargo test --workspace | |
| - name: Clippy | |
| run: cargo clippy --workspace --all-targets -- -D warnings | |
| # Pull requests (and manual dispatch): build an installable debug APK, signed | |
| # with AGP's auto-generated, ephemeral debug keystore (nothing to configure). | |
| debug-apk: | |
| name: Debug APK (ephemeral signing) | |
| needs: test | |
| if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - name: Build builder image (layer-cached) | |
| uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 | |
| with: | |
| context: docker | |
| tags: ntrack-builder:latest | |
| load: true | |
| cache-from: type=gha,scope=ntrack-builder | |
| cache-to: type=gha,mode=max,scope=ntrack-builder | |
| - name: Build debug APK | |
| # Tests already ran in the `test` job; skip the in-container suite. | |
| run: SKIP_IMAGE_BUILD=1 SKIP_TESTS=1 ./build.sh | |
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: ntrack-debug-apk | |
| path: dist/ntrack-debug.apk | |
| if-no-files-found: error | |
| # Tags (v*): build a release APK signed with the persistent key from repo | |
| # secrets and attach it to the GitHub Release. See docs/RELEASING.md. | |
| release-apk: | |
| name: Release APK (signed) | |
| needs: test | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # create the GitHub Release and upload the APK asset | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - name: Build builder image (layer-cached) | |
| uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 | |
| with: | |
| context: docker | |
| tags: ntrack-builder:latest | |
| load: true | |
| cache-from: type=gha,scope=ntrack-builder | |
| cache-to: type=gha,mode=max,scope=ntrack-builder | |
| - name: Decode signing keystore | |
| env: | |
| RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }} | |
| run: | | |
| if [ -z "$RELEASE_KEYSTORE_BASE64" ]; then | |
| echo "::error::Missing secret RELEASE_KEYSTORE_BASE64 (see docs/RELEASING.md)" | |
| exit 1 | |
| fi | |
| echo "$RELEASE_KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/ntrack-release.jks" | |
| - name: Resolve version name from tag | |
| id: ver | |
| # refs/tags/v0.2.0 -> 0.2.0 | |
| run: echo "name=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | |
| - name: Build signed release APK | |
| env: | |
| NTRACK_KEYSTORE: ${{ runner.temp }}/ntrack-release.jks | |
| NTRACK_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }} | |
| NTRACK_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }} | |
| NTRACK_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }} | |
| NTRACK_VERSION_NAME: ${{ steps.ver.outputs.name }} | |
| NTRACK_VERSION_CODE: ${{ github.run_number }} | |
| run: SKIP_IMAGE_BUILD=1 SKIP_TESTS=1 ./build.sh release | |
| - name: Publish APK to the GitHub Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| asset="ntrack-${GITHUB_REF_NAME}.apk" | |
| cp dist/ntrack-release.apk "$asset" | |
| # Create the release for this tag (with auto notes) and attach the | |
| # APK; on a re-run the release exists, so fall back to uploading. | |
| gh release create "$GITHUB_REF_NAME" \ | |
| --title "ntrack ${GITHUB_REF_NAME}" \ | |
| --generate-notes \ | |
| "$asset" \ | |
| || gh release upload "$GITHUB_REF_NAME" "$asset" --clobber | |
| - name: Publish APK to Zapstore | |
| # Publish the same signed APK to the Zapstore app store over Nostr, | |
| # signed with our publishing key. "yaml-mode with a local APK": | |
| # zapstore.yaml is the source of truth and its release_source points at | |
| # the APK built above (dist/ntrack-release.apk). See docs/RELEASING.md. | |
| env: | |
| SIGN_WITH: ${{ secrets.ZAPSTORE_NOSTR_NSEC }} | |
| run: | | |
| if [ -z "$SIGN_WITH" ]; then | |
| echo "::error::Missing secret ZAPSTORE_NOSTR_NSEC (see docs/RELEASING.md)" | |
| exit 1 | |
| fi | |
| # Pinned zsp release (https://github.com/zapstore/zsp); bump to upgrade. | |
| # Pin the asset's SHA-256 as well: this step runs in the same job as the | |
| # decoded signing keystore (still on disk in RUNNER_TEMP) and the | |
| # Zapstore nsec, so a swapped-out upstream binary could exfiltrate both. | |
| # Verify before exec. Update ZSP_SHA256 together with ZSP_VERSION. | |
| ZSP_VERSION=0.4.10 | |
| ZSP_SHA256=a1f73e3f89935e53c0be2fb210fbe9a0da13f693a77627053a208332d8351394 | |
| curl -fsSL -o "$RUNNER_TEMP/zsp" \ | |
| "https://github.com/zapstore/zsp/releases/download/v${ZSP_VERSION}/zsp-${ZSP_VERSION}-linux-amd64" | |
| echo "${ZSP_SHA256} $RUNNER_TEMP/zsp" | sha256sum -c - | |
| chmod +x "$RUNNER_TEMP/zsp" | |
| # --quiet: no prompts, auto-confirm (CI). --skip-metadata: keep | |
| # zapstore.yaml authoritative instead of enriching from external sources. | |
| "$RUNNER_TEMP/zsp" publish zapstore.yaml --quiet --skip-metadata |