1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
name: ci
# Three questions, answered on every push and once a day:
# host does the crate build, lint, and pass its host tests?
# cross-check do the native halves compile for the targets they claim?
# demo does the walkthrough pass on the iOS Simulator, the Android emulator and the
# HarmonyOS emulator, against day's main or newest release?
#
# No Cargo.lock is committed, here or in demo/: every run resolves day afresh. A push builds against the
# head of day's main (and of every other Day repository it uses), and the nightly run against
# the newest releases on crates.io (daybrite/actions' day-deps). A red push run after a day push
# is the signal, not a nuisance; a red nightly run means this crate needs a day that is not
# released yet. There is no pinned lock for a local `day patch` table to rewrite and commit by
# accident.
on:
push:
branches:
tags:
pull_request:
workflow_dispatch:
inputs:
day-main:
description: Build against day's main branch instead of the newest release
type: boolean
default: false
schedule:
# Daily: day's main moves, and so does CameraX, on weeks nobody pushes.
- cron: "0 7 * * *"
# The repository's own jobs run this checkout's code with a read-only token. The write grants
# sit on the job that calls the shared workflow, whose release and Pages jobs alone use them;
# its build legs, which run this code too, narrow their token to read-only themselves.
permissions:
contents: read
jobs:
host:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
# Day from crates.io, or from main on a push (daybrite/actions day-deps).
- uses: daybrite/actions/.github/actions/day-deps@v1
with:
day-deps: ${{ inputs.day-main && 'main' || 'auto' }}
- run: cargo fmt --all -- --check
- run: cargo clippy --all-targets -- -D warnings
# The pure half: report decoding, photo payloads, state labels.
- run: cargo test
# The native halves compile for their targets. A link is not attempted here (the demo below
# does that inside a real app), but an objc2 call that no longer type-checks, a JNI signature
# drift in the Android arm, or a C shim that stopped matching the NDK headers fails here in a
# minute rather than in an emulator.
cross-check:
strategy:
fail-fast: false
matrix:
include:
-
-
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
# Day from crates.io, or from main on a push (daybrite/actions day-deps).
- uses: daybrite/actions/.github/actions/day-deps@v1
with:
day-deps: ${{ inputs.day-main && 'main' || 'auto' }}
- run: cargo clippy --target ${{ matrix.target }} --features ${{ matrix.features }} -- -D warnings
# The proof: the demo app, driven end to end on each platform by the shared Day workflow. It
# builds against day's main or newest release, runs the walkthrough, and fails on a failed assertion or a
# blank capture. Screenshots are uploaded per target, and a tag build attaches them to the
# release. The HarmonyOS leg is where the C shim meets the NDK and links.
#
# Two walkthroughs. dayscript/camera.yaml asserts the page as a first launch shows it, with
# the permission undecided: the Allow button raises an OS dialog a dayscript cannot dismiss,
# so the viewfinder stays idle there. On Android the emulator has a virtual camera, so that leg
# launches with the permission already granted (`grant-permissions` becomes `day launch
# --grant camera`, which marks it with `pm grant` between the install and the start) and runs
# dayscript/camera-capture.yaml instead: the session runs, the shutter writes a photo, the page
# shows it, and the other camera comes up. The iOS Simulator has no camera at all, so the CLI
# refuses a camera grant there, and the walkthrough stays the first-launch one.
demo:
uses: daybrite/actions/.github/workflows/dayapp.yml@v1
permissions:
contents: write # release-asset upload on tag builds
id-token: write # crates.io Trusted Publishing (publish-crates)
secrets: inherit
with:
project-path: demo
targets: ios-uikit, android-material, harmony-arkui
day-deps: ${{ inputs.day-main && 'main' || 'auto' }}
# On a version tag, after every leg passed: the library crates to crates.io.
publish-crates: true
scripts: dayscript/camera.yaml
target-scripts: |
android-material: dayscript/camera-capture.yaml
grant-permissions: |
android-material: camera
preflight-checks: fmt, clippy, test
ios-devices: |
device=iPhone, orientation=portrait
android-devices: |
device=pixel_7, os=36, orientation=portrait