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
23 changes: 23 additions & 0 deletions .github/scripts/launch-smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,28 @@ for attempt in 1 2 3; do
sleep 5
done

# `adb install` returns when the install session commits, which is before the
# package manager has the app indexed. Starting the activity in that window
# fails with "Error type 3 / Activity class does not exist" -- the app is on
# disk, the launcher just cannot see it yet. That failure looks identical to a
# genuinely broken build, and it is what the job's reputation as a flake was
# partly built on (#247, #252, #262).
#
# Wait for the package manager to answer instead of sleeping a fixed amount:
# a slow CI emulator can take several seconds, a fast one none at all.
echo "Waiting for the package manager to see the app"
for _ in $(seq 1 30); do
if adb shell pm path com.markleaf.notes 2>/dev/null | tr -d '\r' | grep -q '^package:'; then
echo "Package indexed."
break
fi
sleep 2
done

if ! adb shell pm path com.markleaf.notes 2>/dev/null | tr -d '\r' | grep -q '^package:'; then
echo "Package manager never listed com.markleaf.notes after a successful install"
exit 1
fi

adb shell am start -W -n com.markleaf.notes/.MainActivity
adb shell pidof com.markleaf.notes
12 changes: 12 additions & 0 deletions .github/workflows/android-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ jobs:
app/build/outputs/roborazzi/
app/build/reports/roborazzi/
if-no-files-found: ignore
# Only uploaded when the visual check fails, and only useful while
# someone is looking at that failure. A week outlives any run worth
# re-opening; the goldens themselves live in the repository (#247).
retention-days: 7

- name: Run release lint (hard gate)
run: ./gradlew :app:lintRelease
Expand All @@ -85,6 +89,9 @@ jobs:
name: lint-report-release
path: app/build/reports/lint-results-release.html
if-no-files-found: ignore
# Same reasoning as the Roborazzi diffs: a failure-only report that is
# read while the failure is fresh, or not at all (#247).
retention-days: 7

- name: Build release APK with R8 (hard gate, unsigned ok)
run: ./gradlew :app:assembleRelease
Expand Down Expand Up @@ -245,6 +252,11 @@ jobs:
name: roborazzi-goldens-linux
path: app/src/test/snapshots/roborazzi/
if-no-files-found: error
# Longer than the failure-only artifacts: this one is downloaded and
# committed by hand, so it has to survive the gap between dispatching
# the run and getting round to the commit. Still not 90 days — once
# committed the goldens are in the repository (#247).
retention-days: 30

release:
if: startsWith(github.ref, 'refs/tags/v')
Expand Down
52 changes: 52 additions & 0 deletions docs/assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Public assets

What each file here is for, and — for the ones recorded from a running build —
which version they show. Two things went unrecorded before this file existed:
why unreferenced files are kept, and how anyone would notice a clip has gone
stale (#258).

## Demo clips

| File | Surface | Recorded on |
|---|---|---|
| `markleaf-tablet-<lang>.gif` (6) | Landing story 01 + README hero, one per language | v2.30.0 |
| `markleaf-demo.gif` | Older single-language demo | v2.23.0 |

`scripts/verify-landing-versions.ps1` asserts that each language surface points
at its **own** clip and that the file exists — a page referencing another
language's GIF renders fine and would otherwise ship silently.

Nothing asserts that a clip still matches the current UI. That is a judgement
call, not a check: re-record when a change would make the clip misleading, and
update the version above when you do. A clip showing an older layout is only a
problem once the layout it shows is gone.

## Screenshots

`markleaf-editor-*.webp`, `markleaf-privacy-*.webp`, `markleaf-tags-*.webp` —
the landing page screenshots, in 720px and 1280px variants. The version they
show is carried in each page's `<figcaption>`, which
`verify-landing-versions.ps1` requires to agree across the six languages.

### `markleaf-preview-720.webp` / `markleaf-preview-1280.webp` — kept deliberately

**Nothing in this repository references these two.** They are kept anyway, and
this is the record of that decision so a future cleanup does not have to guess.

They were served from GitHub Pages under stable URLs
(`https://jeiel85.github.io/markleaf-android/assets/markleaf-preview-1280.webp`)
while they were in use, and those URLs may be linked from places outside this
repository — a store listing draft, a forum post, a bookmark. Deleting the
files breaks those links for no benefit: together they are ~93 KB and cost
nothing to keep.

Remove them only if the Pages site itself moves or is retired, which breaks the
URLs regardless.

## Store and brand

| File | Use |
|---|---|
| `markleaf-feature-graphic-1024x500.png` | Play Console feature graphic |
| `markleaf-playstore-icon-512.png` | Play Console app icon |
| `logo.svg` | Landing header |
51 changes: 51 additions & 0 deletions scripts/verify-landing-versions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,57 @@ foreach ($file in $readmeFiles) {
}
}

# ---- 언어별 데모 GIF: 각 페이지가 자기 언어 클립을 가리키는지 ----
#
# README.ko.md 가 markleaf-tablet-en.gif 를 가리켜도 렌더링은 멀쩡하므로 조용히
# 나간다 — 버전 표기에서 이 검사가 막아 주는 것과 같은 종류의 구멍이다 (#258).
# 언어 코드는 파일명 규칙에서 끌어온다: index.html/README.md 는 en, 나머지는 접미사.
$assetPairs = @(
@{ File = "docs/index.html"; Lang = "en" }
@{ File = "docs/index.ko.html"; Lang = "ko" }
@{ File = "docs/index.ja.html"; Lang = "ja" }
@{ File = "docs/index.de.html"; Lang = "de" }
@{ File = "docs/index.es.html"; Lang = "es" }
@{ File = "docs/index.fr.html"; Lang = "fr" }
@{ File = "README.md"; Lang = "en" }
@{ File = "README.ko.md"; Lang = "ko" }
@{ File = "README.ja.md"; Lang = "ja" }
@{ File = "README.de.md"; Lang = "de" }
@{ File = "README.es.md"; Lang = "es" }
@{ File = "README.fr.md"; Lang = "fr" }
)

Write-Host "`n데모 GIF ($($assetPairs.Count)개 표면)"
foreach ($pair in $assetPairs) {
$path = Resolve-UnderRoot $pair.File
if (-not (Test-Path -LiteralPath $path)) {
Add-Failure (" FAIL {0,-20} 파일이 없습니다." -f $pair.File)
continue
}
$text = Get-Content -Raw -Encoding utf8 -LiteralPath $path
$expected = "markleaf-tablet-$($pair.Lang).gif"

# 이 표면이 참조하는 태블릿 GIF 를 전부 모아, 자기 언어 것만 있는지 본다.
$referenced = @(
[regex]::Matches($text, 'markleaf-tablet-([a-z]{2})\.gif') |
ForEach-Object { $_.Value } | Sort-Object -Unique
)

if ($referenced.Count -eq 0) {
Add-Failure (" FAIL {0,-20} 태블릿 데모 GIF 참조가 없습니다 (기대 {1})." -f $pair.File, $expected)
} elseif ($referenced -contains $expected -and $referenced.Count -eq 1) {
# 에셋 자체가 있어야 참조가 의미를 갖는다.
$assetPath = Join-Path $docsPath "assets/$expected"
if (Test-Path -LiteralPath $assetPath) {
Write-Host (" OK {0,-20} {1}" -f $pair.File, $expected) -ForegroundColor Green
} else {
Add-Failure (" FAIL {0,-20} {1} 을 가리키는데 docs/assets 에 그 파일이 없습니다." -f $pair.File, $expected)
}
} else {
Add-Failure (" FAIL {0,-20} 기대 {1}, 실제 -> {2}" -f $pair.File, $expected, ($referenced -join ', '))
}
}

# ---- 스크린샷(figcaption): 릴리스 버전과 별개, 언어 간 일치만 확인 ----
$screenshotUnique = @($screenshotVersions | Sort-Object -Unique)
if ($screenshotUnique.Count -le 1) {
Expand Down