docs: add Gitea workflows, issue/PR templates, README and licence notice
ci.yml calls `scripts/ci.sh` rather than restating the checks: a workflow that reimplements them becomes a second definition of "done", and the two drift. Android runs as a separate job. It fails when the SDK is absent while ci.sh skips it — a developer should not be blocked by a missing toolchain, but a silently skipped Android build in CI means regressions ship unnoticed. Every action is pinned to an exact version. LICENSE.md records that no licence is chosen yet, and why it is not a formality: the choice is upstream of the UI toolkit decision, since Slint is GPL-3.0. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
name: CI
|
||||
|
||||
# Section 10.4 requires every PR to pass these checks. This workflow does not
|
||||
# reimplement them: it runs `scripts/ci.sh`, which is the single source of truth
|
||||
# for what must pass. Reimplementing the steps here is how CI and local checks
|
||||
# drift apart, and then one of them is lying to you.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
# Superseded PR runs are cancelled rather than left to finish and report on a
|
||||
# commit that no longer exists.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
# Matches the act_runner label in .gitea/workflows/README.md. Change both
|
||||
# together if the runner is registered under a different label.
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4.1.7
|
||||
|
||||
# Pinned to an exact version, never a floating tag. A floating tag lets
|
||||
# upstream change what runs in your CI without review, which is a supply
|
||||
# chain problem, not a convenience.
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
# rust-toolchain.toml pins the channel and components, so this action
|
||||
# installs exactly what the project asks for and CI matches local.
|
||||
|
||||
- name: Cache cargo
|
||||
uses: Swatinem/rust-cache@v2.7.5
|
||||
|
||||
- name: Cache cargo registry
|
||||
uses: actions/cache@v4.1.2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry/index
|
||||
~/.cargo/registry/cache
|
||||
~/.cargo/git/db
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
|
||||
- name: Run all checks
|
||||
# scripts/ci.sh runs: fmt --check, clippy -D warnings, cargo test, the 5 MB
|
||||
# size gate, Android lint (skipped loudly without an SDK), and gitleaks.
|
||||
#
|
||||
# A skip inside ci.sh prints SKIP with the reason and is listed in the
|
||||
# summary as "NOT a pass", so an unverified Android build can never be
|
||||
# mistaken for a verified one.
|
||||
run: bash scripts/ci.sh
|
||||
|
||||
- name: Upload the release daemon
|
||||
# Section 10.5 requires releases to carry SHA-256 checksums. Producing
|
||||
# the checksum here means the release pipeline never has to trust an
|
||||
# artifact it did not build itself.
|
||||
if: always()
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BIN="${CARGO_TARGET_DIR:-$HOME/.blocker-target}/release/blocker-daemon"
|
||||
mkdir -p dist
|
||||
if [ -f "$BIN" ]; then
|
||||
cp "$BIN" dist/blocker-daemon
|
||||
sha256sum dist/blocker-daemon > dist/blocker-daemon.sha256
|
||||
else
|
||||
echo "release daemon not built; nothing to upload"
|
||||
fi
|
||||
|
||||
- uses: actions/upload-artifact@v4.4.3
|
||||
if: always()
|
||||
with:
|
||||
name: blocker-daemon-linux
|
||||
path: dist/
|
||||
if-no-files-found: warn
|
||||
|
||||
# A separate job, rather than a step, for two reasons: it needs a different
|
||||
# runner label (a runner with the Android SDK), and its failure should be
|
||||
# legible on its own rather than buried in the middle of the CI output.
|
||||
#
|
||||
# Note the asymmetry with ci.sh, which is deliberate. ci.sh SKIPS Android when
|
||||
# no SDK is present, because a developer running checks locally should not be
|
||||
# blocked by a missing toolchain. This job FAILS when the SDK is absent,
|
||||
# because a silently skipped Android build in CI means Android regressions ship
|
||||
# unnoticed. Same check, opposite defaults, for opposite contexts.
|
||||
android:
|
||||
runs-on: android-build
|
||||
timeout-minutes: 60
|
||||
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.7
|
||||
|
||||
- uses: actions/setup-java@v4.4.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '17'
|
||||
|
||||
- uses: android-actions/setup-android@v3.2.2
|
||||
|
||||
- name: Accept SDK licences
|
||||
run: yes | sdkmanager --licenses > /dev/null 2>&1 || true
|
||||
|
||||
- name: Cache Gradle
|
||||
uses: actions/cache@v4.1.2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('android/**/*.gradle.kts') }}
|
||||
restore-keys: ${{ runner.os }}-gradle-
|
||||
|
||||
# Sideload flavour only. There is deliberately no Play Store signing path
|
||||
# in CI: sections 6.8 and 4.1 record that the strongest friction
|
||||
# (Stubborn level, Device Admin uninstall block) is hostile to Play Store
|
||||
# policy and is intended for sideload or F-Droid distribution.
|
||||
- name: Lint and assemble release
|
||||
working-directory: android
|
||||
run: ./gradlew lint assembleRelease
|
||||
Reference in New Issue
Block a user