Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
3883bf5
Prepare Mac App Store distribution foundations
frathe Sep 29, 2026
2ec93e7
Add sandboxed XPC workers for Apple Store builds
frathe Sep 29, 2026
a293137
Qualify sandbox bookmark transfer to image workers
frathe Sep 29, 2026
03a2eaf
Preserve scoped file access through scans and saved collections
frathe Sep 29, 2026
93c3040
Preserve native opening authority through capture and shutdown
frathe Sep 29, 2026
cae44c9
Retain native save access through scoped atomic image writes
frathe Sep 29, 2026
beb8491
Validate signed Apple runtime code in the application bundle
frathe Sep 29, 2026
f0565d1
Qualify universal Apple Store builds and sandbox file access
frathe Sep 30, 2026
cd063e9
Verify Apple runtime provenance and retain Abseil privacy manifests
frathe Sep 30, 2026
38ec88e
Restore Store picker folder navigation with explicit consent
frathe Sep 30, 2026
75356d9
Share Store folder consent across dropped and opened images
frathe Sep 30, 2026
b98d848
Restore Store guard inventory and probe multiple-file navigation
frathe Sep 30, 2026
62661a1
Remember folder approvals and prepare signed Store packaging
frathe Sep 30, 2026
da2df0c
Document App Store handoff checklist and qualification evidence
frathe Sep 30, 2026
710ba5c
Prepare manually approved Apple Store CI signing
frathe Sep 30, 2026
71fd577
Preserve scoped metadata sorting and moved analysis sources
frathe Sep 30, 2026
0ecfaf6
Scope development worker fixture to ordinary builds
frathe Sep 30, 2026
0a670e6
Pin Apple signing workflow actions to verified commits
frathe Sep 30, 2026
4a80484
Record clean Apple Store preparation review evidence
frathe Sep 30, 2026
8533342
feat: animate Trane in console help
frathe Sep 30, 2026
bb6ce5d
Fix Windows image path transport into PowerShell
frathe Sep 30, 2026
44b04e0
Record Windows path security qualification
frathe Sep 30, 2026
6146a9e
Restrict release write authority to publication
frathe Sep 30, 2026
8505c43
Preserve cancellation during broker startup and terminal help
frathe Sep 30, 2026
91b8805
Pin release publication actions to reviewed commits
frathe Sep 30, 2026
382a40d
Bound secondary JPEG source reads during Save and Export
frathe Sep 30, 2026
1439746
Add fixed pixel screenshot window mode with terminal picker
frathe Oct 1, 2026
d402f38
Restore responsive Store folder consent and current bookmark parents
frathe Oct 1, 2026
d82483f
Normalize Windows paths in moved folder consent regression
frathe Oct 1, 2026
56b6166
Preserve screenshot pixels across scale changes and terminal interrup…
frathe Oct 1, 2026
a664aad
Bind metadata removal and export to the inspected source
frathe Oct 1, 2026
f36f1ca
Honor termination signals received while restoring the picker
frathe Oct 1, 2026
2e392a9
Record completed screenshot and Store consent verification
frathe Oct 1, 2026
c8b5b4e
Archive completed plans and reconcile historical gate notes
frathe Oct 1, 2026
22be7bf
Observe termination received during animated help restoration
frathe Oct 1, 2026
f3c5354
Separate help interrupt and termination notification capacity
frathe Oct 1, 2026
810001c
Install native open handling before interactive size selection
frathe Oct 1, 2026
fa21e17
Verify inspected JPEG sources before the clean no-op shortcut
frathe Oct 1, 2026
63382e7
Expect refusal when confirmed JPEG becomes clean
frathe Oct 1, 2026
3453f1b
Recheck JPEG content before metadata removal commits
frathe Oct 1, 2026
c7687f7
Record clean follow-up reviews and refreshed Store test bundle
frathe Oct 1, 2026
3e827c1
Record approved native folder access and relaunch qualification
frathe Oct 1, 2026
a46076c
Close qualified Open With checklist and refresh test app path
frathe Oct 1, 2026
04e5e16
Fix sandboxed macOS image clipboard publication
frathe Oct 1, 2026
01b5a18
Keep macOS clipboard image data available after exit
frathe Oct 1, 2026
4b238da
Record qualified Store clipboard fix and close the blocker
frathe Oct 1, 2026
3eafe3d
Fix EXIF map cache freshness and OSM license access
frathe Oct 1, 2026
c8fd4df
Bind EXIF tile delivery to the current map view
frathe Oct 1, 2026
951f236
Record the scoped FOSSA research-reference disposition
frathe Oct 1, 2026
c89c74d
Preserve decoded foreground map tiles through UI delivery
frathe Oct 1, 2026
68d89d6
Discard directly delivered no-store tile responses
frathe Oct 1, 2026
2e971e8
Retire map renderer delivery under captured session ownership
frathe Oct 1, 2026
1a7941a
Revalidate tiles with invalid freshness headers
frathe Oct 1, 2026
e72ef05
Parse quoted cache directives and honor tile Vary wildcard
frathe Oct 1, 2026
9ae519c
Reject malformed cache directive equals boundaries
frathe Oct 1, 2026
29b00a8
Retire map frames when Location is hidden
frathe Oct 1, 2026
e2ca161
Include response delay in map tile freshness
frathe Oct 1, 2026
daf05af
Release retired map pixels before queued UI delivery
frathe Oct 1, 2026
bb0f77b
Saturate overflowing tile response Age values
frathe Oct 1, 2026
3da5f98
Saturate valid overflowing max-age directives
frathe Oct 1, 2026
37d7aeb
added OSM copiright according to license requirements.
frathe Oct 3, 2026
b69171b
fix(macstore): embed current version in packaged executable
frathe Oct 3, 2026
1703922
docs(macstore): close initial App Store release records
frathe Oct 11, 2026
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
9 changes: 7 additions & 2 deletions .github/testshards/internal-ui.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
# baseline-run: 34627413846
# baseline-attempts: 1
# weights: single CI attempt; projected test sums, not measured shard runtimes
# ui-1: 270 entries, 470.520s projected weight sum
# ui-1: 272 entries, 470.520s projected weight sum
# ui-2: 255 entries, 470.530s projected weight sum
# ui-3: 221 entries, 504.870s projected weight sum
# ui-3: 224 entries, 504.870s projected weight sum
# rebalance: 27 whole-test moves; slowest projected sum within 5% of mean
# evidence: finished_refactorings/2026-09-11-ui-shard-rebalance.md
# name shard
Expand Down Expand Up @@ -170,6 +170,7 @@ TestInvalidateLoad_CancelsPriorLoadContext ui-1
TestKey0YieldsCopySelectionAndResetsRotation ui-1
TestLastUpdateCheckDay_ConcurrentWithCurrentPreferences ui-1
TestLaunchOptions_AppliesEverySetting ui-1
TestLaunchOptions_FixedSizeGeometryAndModes ui-1
TestLaunchOptions_PictureFrameSpentWhenLaunchCancelled ui-1
TestLaunchOptions_PictureFrameSpentWhenResetBeforeScan ui-1
TestLaunchOptions_PictureFrameSpentWhenTheLaunchLoadsNothing ui-1
Expand Down Expand Up @@ -234,6 +235,7 @@ TestShowExifWindow_OpensAndRaisesSameWindow ui-1
TestShowImage_StartsLoadLifecycle ui-1
TestShow_ResetsZoomOnNavigation ui-1
TestShutdownStopsPictureFrameWithQueuedAdvance ui-1
TestSiblingFolderConsentLifecycle ui-1
TestSlideInterval_DefaultsBeforePictureFrameModeEverRuns ui-1
TestStartWindowPosPolling_TestDriverGetsNoopStop ui-1
TestStartup_LoadsSavedSecondaryWindowGeometry ui-1
Expand Down Expand Up @@ -603,6 +605,7 @@ TestExportAs_NoOpWithNothingLoaded ui-3
TestExportAs_SuggestsTheSourceNameWithTheNewExtensionInItsOwnFolder ui-3
TestExportAs_WritesTheDisplayedFrameToThePickedPath ui-3
TestExportItem_DisabledInitiallyAndEnabledOnceAnImageLoads ui-3
TestExportRetiresNativeDestination ui-3
TestFavoritesMenuItemOpensStoredFilesThroughViewer ui-3
TestFileSnapshot_KeysAndGenerationMoveTogether ui-3
TestFindMoreLikeThisActionsCaptureRankedSources ui-3
Expand Down Expand Up @@ -654,10 +657,12 @@ TestMosaicDrain_ClosesWindowAndClearsTransientState ui-3
TestMosaicShutdown_ClosesWindowBeforeTheEventLoopStops ui-3
TestMosaicSources_UsesExplicitSelectionExclusively ui-3
TestMosaicWallpaper_RejectsOverlapAndDeletesOnlyFailedCopy ui-3
TestNativeSelectionOpeningOwnership ui-3
TestNormalizePreferenceDefaults ui-3
TestOpenFileDialog_RunsChooserInBackground ui-3
TestOpenInitialFiles_OpensPendingWhenNothingWasDelivered ui-3
TestOpenWithHandler_DeliveryMergesWhenMergeModeIsOn ui-3
TestOpenWithShutdownReleasesUndeliveredNativeInput ui-3
TestPerformDelete_OSFailureKeepsTheFileAndToastsAnError ui-3
TestPerformUpdate_RecordsRelaunchThenQuits ui-3
TestPictureFrameMenu_DetachedMenuReachesTheWindowEdge ui-3
Expand Down
128 changes: 128 additions & 0 deletions .github/workflows/apple-store.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Apple Store candidate

# Signing qualification only. Upload/TestFlight/release automation is separate.
on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: apple-store-candidate
cancel-in-progress: false

jobs:
test:
if: github.repository == 'frathe/picfetch' && github.ref == 'refs/heads/main'
uses: ./.github/workflows/ci.yml

build:
needs: test
runs-on: macos-15
timeout-minutes: 60
outputs:
artifact-id: ${{ steps.qualified.outputs.artifact-id }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: '3.12'
- name: Download pinned runtime archives
# The packager checks exact size/hash and Microsoft code signatures.
run: |
curl --fail --location --retry 3 --proto '=https' --proto-redir '=https' \
https://github.com/microsoft/onnxruntime/releases/download/v1.29.0/onnxruntime-osx-arm64-1.29.0.tgz \
--output "$RUNNER_TEMP/onnx-arm64.tgz"
curl --fail --location --retry 3 --proto '=https' --proto-redir '=https' \
https://github.com/microsoft/onnxruntime/releases/download/v1.23.2/onnxruntime-osx-x86_64-1.23.2.tgz \
--output "$RUNNER_TEMP/onnx-amd64.tgz"
- name: Build and inspect universal sandbox app
env:
APPLE_STORE_OUTPUT_DIR: ${{ runner.temp }}/apple-store-qualified
APPLE_STORE_ARM64_ARCHIVE: ${{ runner.temp }}/onnx-arm64.tgz
APPLE_STORE_AMD64_ARCHIVE: ${{ runner.temp }}/onnx-amd64.tgz
run: make apple-store-package-local
- name: Run native packaging guards
env:
PICFETCH_TEST_MAC_APP_BUNDLE: ${{ runner.temp }}/apple-store-qualified/PicFetch.app
run: python3 -m unittest discover -s scripts/macstorepackage
- name: Archive qualification artifact and approval summary
env:
SOURCE_SHA: ${{ github.sha }}
run: |
tar -czf "$RUNNER_TEMP/apple-store-qualified.tgz" -C "$RUNNER_TEMP/apple-store-qualified" PicFetch.app manifest.json
{
echo '### Apple Store signing approval'
echo "Source revision: $SOURCE_SHA"
echo 'Full CI and native packaging guards passed for this candidate.'
echo 'Approve the apple-store-signing environment to sign this artifact.'
echo 'The signed installer is a qualification candidate. SDK/privacy and Apple acceptance remain open.'
echo 'This workflow does not upload to Apple or release the app.'
shasum -a 256 "$RUNNER_TEMP/apple-store-qualified.tgz"
} >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
id: qualified
with:
name: apple-store-qualified-${{ github.sha }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/apple-store-qualified.tgz
retention-days: 7
if-no-files-found: error

sign:
needs: build
runs-on: macos-15
timeout-minutes: 30
# Required reviewer is Ronin (frathe); environment allows main only.
# Configure the environment before storing any signing secrets.
environment: apple-store-signing
env:
APPLE_STORE_TEAM_ID: ${{ vars.APPLE_STORE_TEAM_ID }}
APPLE_STORE_APP_IDENTITY: ${{ vars.APPLE_STORE_APP_IDENTITY }}
APPLE_STORE_INSTALLER_IDENTITY: ${{ vars.APPLE_STORE_INSTALLER_IDENTITY }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: '3.12'
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
artifact-ids: ${{ needs.build.outputs.artifact-id }}
merge-multiple: true
path: ${{ runner.temp }}/apple-store-download
- name: Restore same-run qualification artifact
run: |
mkdir "$RUNNER_TEMP/apple-store-qualified"
tar -xzf "$RUNNER_TEMP/apple-store-download/apple-store-qualified.tgz" -C "$RUNNER_TEMP/apple-store-qualified"
- name: Sign with temporary Keychain
env:
APPLE_STORE_APP: ${{ runner.temp }}/apple-store-qualified/PicFetch.app
APPLE_STORE_SIGNED_OUTPUT_DIR: ${{ runner.temp }}/apple-store-signed
APPLE_STORE_APP_P12_BASE64: ${{ secrets.APPLE_STORE_APP_P12_BASE64 }}
APPLE_STORE_APP_P12_PASSWORD: ${{ secrets.APPLE_STORE_APP_P12_PASSWORD }}
APPLE_STORE_INSTALLER_P12_BASE64: ${{ secrets.APPLE_STORE_INSTALLER_P12_BASE64 }}
APPLE_STORE_INSTALLER_P12_PASSWORD: ${{ secrets.APPLE_STORE_INSTALLER_P12_PASSWORD }}
APPLE_STORE_PROFILE_BASE64: ${{ secrets.APPLE_STORE_PROFILE_BASE64 }}
APPLE_STORE_WORKER_PROFILE_BASE64: ${{ secrets.APPLE_STORE_WORKER_PROFILE_BASE64 }}
run: python3 scripts/macstorepackage/ci_sign.py
- name: Clean temporary credentials
if: ${{ always() }}
run: python3 scripts/macstorepackage/ci_sign.py --cleanup
- name: Upload verified candidate and provenance
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: apple-store-signed-${{ github.sha }}-${{ github.run_attempt }}
path: |
${{ runner.temp }}/apple-store-signed/PicFetch.pkg
${{ runner.temp }}/apple-store-signed/manifest.json
retention-days: 14
if-no-files-found: error
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ jobs:
- name: Check formatting
run: make fmt-check

- name: Check Apple Store packaging policy
# Portable policy/resource tests run here; signed native artifact guards
# require a locally built macOS bundle and are qualified separately.
run: python3 -m unittest discover -s scripts/macstorepackage

- name: Check search review controls
run: |
node --version
Expand Down
27 changes: 19 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- "v*"

permissions:
contents: write
contents: read

jobs:
# The gate: a tag push runs the full CI suite (format, vet, build, test)
Expand All @@ -29,6 +29,8 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@v7
Expand Down Expand Up @@ -60,6 +62,8 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@v7
Expand Down Expand Up @@ -219,37 +223,41 @@ jobs:

release:
needs: [build-macos, build-cross, sign-windows]
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false

- name: Download macOS artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: picfetch-macos-arm64
path: dist

- name: Download Intel macOS artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: picfetch-macos-x86_64
path: dist

- name: Download Linux artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: picfetch-linux
path: dist

- name: Download signed Windows artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: picfetch-windows-signed
path: dist

- name: Set up Go for final notice inspection
uses: actions/setup-go@v7
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
cache-dependency-path: go.sum
Expand All @@ -261,7 +269,10 @@ jobs:
go run ./scripts/updaternotices -artifact dist/picfetch-linux-amd64.tar.gz -artifact dist/picfetch-linux-arm64.tar.gz

- name: Create GitHub release
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
# Both inputs are declared in this pinned action's action.yml.
# noinspection UndefinedParamsPresent
files: dist/*
# noinspection UndefinedParamsPresent
body_path: .github/release-notes.md
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ node_modules/
.env.local
.scratch/
.tools/
__pycache__/
Loading
Loading