name: Kanban
options:
  bundleIdPrefix: dev.rzen.indie
  deploymentTarget:
    macOS: "26.0"
  xcodeVersion: "26.0"
  defaultConfig: Debug

packages:
  Yams:
    url: https://github.com/jpsim/Yams.git
    from: 6.0.0
  # apple/swift-markdown — the card window's Preview parser (05-card-window.md ▸ Preview).
  # Pinned to the next *minor* rather than the next major because the package is pre-1.0: a
  # `from:` range here would silently accept 0.9's breaking changes, which is not what `from:`
  # means for Yams at 6.x.
  swift-markdown:
    url: https://github.com/apple/swift-markdown.git
    minorVersion: 0.8.0
  # The About window: app icon, version/build from the stamped Info.plist, and the bundled
  # LICENSE/CHANGELOG documents. Pre-1.0 like swift-markdown, same pinning logic.
  IndieAbout:
    url: https://git.rzen.dev/rzen/indie-about.git
    minorVersion: 0.2.2

settings:
  base:
    SWIFT_VERSION: "6.0"
    MACOSX_DEPLOYMENT_TARGET: "26.0"
    DEVELOPMENT_TEAM: ${APPLE_TEAM_ID}
    ENABLE_USER_SCRIPT_SANDBOXING: NO

# **One app target** (12-editions.md ▸ The target, re-ruled 2026-07-30). Lanework ships as a single
# Mac App Store app, `dev.rzen.indie.Kanban`; **Lanework Pro is a subscription inside it**, not a
# second binary. The 2026-07-27 two-target split — a `KanbanPro` application target, its scheme, its
# bundle id, the `-module-alias Kanban=KanbanPro` test bundle and the twin source files that existed
# only because two bundles claimed different UTI ownership — retired wholesale with the collapse.
#
# What that buys this file: no anchors, no per-target exclusion lists, no second copy of the
# resources. There is one product, one Info.plist, one entitlements file, one Swift module, and one
# `.kanban` UTI **exported** (never imported) by the app that owns it.
#
# libgit2 arrives here with pro-m1 — a dependency of the one target, dormant behind the subscription
# gate rather than the contents of a second download.
targets:
  # MARK: - Lanework

  Kanban:
    type: application
    platform: macOS
    sources:
      - Kanban
      # The bundled template store (09-templates.md ▸ Definition format): real board folders,
      # copied into `Contents/Resources/Templates/` verbatim as a folder reference — the same
      # arrangement `Fixtures/` uses below, and for the same reason. A template is a board, so it
      # must reach the bundle as directories on disk, not as flattened resource files.
      - path: Templates
        type: folder
        buildPhase: resources
      # The About window's documents (LICENSE, CHANGELOG) — bundled so IndieAbout can render
      # them in-app. Apple-inline-Markdown subset only: no `#` headings, no hard-wrapped
      # paragraphs (every newline renders literally).
      - path: LICENSE.md
        type: file
        buildPhase: resources
      - path: CHANGELOG.md
        type: file
        buildPhase: resources
      # The local StoreKit configuration (12-editions.md ▸ Distribution) — the subscription group
      # "Lanework Pro" and its monthly product, mirroring what App Store Connect declares, so the
      # Settings Pro section's subscribe/manage/restore flow is exercisable in Xcode without an ASC
      # product existing yet. Attached to the scheme's run action below.
      #
      # **`buildPhase: none`, deliberately.** It is development configuration, not app content: the
      # scheme reads it, the shipped bundle must never carry it. Listed in the project anyway, for
      # the same reason `KanbanUITests`' verification documents are — visible where it belongs,
      # built into nothing.
      - path: Configuration.storekit
        type: file
        buildPhase: none
    dependencies:
      - package: Yams
      - package: swift-markdown
        product: Markdown
      - package: IndieAbout
    postBuildScripts:
      - script: '"${SRCROOT}/../indie-skills/skills/app-versioning/scripts/update_build_info.sh"'
        name: Update Build Info
        shell: /bin/sh
        basedOnDependencyAnalysis: false
        inputFiles:
          - $(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)
          - $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Info.plist
    settings:
      base:
        # The identifier 1.x shipped under, unchanged: 2.0 updates that App Store record rather
        # than opening a second one (12-editions.md ▸ Distribution, ruled 2026-07-30).
        PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.Kanban
        MARKETING_VERSION: "2.0"
        INFOPLIST_FILE: Kanban/Info.plist
        # `Kanban/Kanban.entitlements` — sandbox, user-selected files, app-scope bookmarks, and
        # `com.apple.security.network.client`, which is **declared now and dormant until Pro
        # ships**: the one binary carries the key, and nothing exercises it until the git
        # provider's remotes do under an active subscription (12 ▸ The target). No App Group and
        # no keychain access group — groups exist to share *between* apps, and there is one app,
        # so app-side state homes in the ordinary sandbox container (`AppStateHome`).
        CODE_SIGN_ENTITLEMENTS: Kanban/Kanban.entitlements
        GENERATE_INFOPLIST_FILE: false
        SWIFT_STRICT_CONCURRENCY: complete
        ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon

  # MARK: - Unit tests
  #
  # The suite, hosted by the app: every test in `KanbanTests/` exercises the storage format, the
  # live store or the UI model through `@testable import Kanban`, so it needs the app's module and
  # its bundle around it. `Fixtures/` rides in as a folder reference for the same reason the
  # templates do — a fixture is a board, and a board is directories on disk.

  KanbanTests:
    type: bundle.unit-test
    platform: macOS
    sources:
      - KanbanTests
      - path: Fixtures
        type: folder
        buildPhase: resources
    dependencies:
      - target: Kanban
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.KanbanTests
        GENERATE_INFOPLIST_FILE: true
        SWIFT_STRICT_CONCURRENCY: complete

  # MARK: - UI tests
  #
  # These launch the real app and drive its menu bar — the slowest, most environment-dependent part
  # of the suite. The accessibility audits (10-accessibility.md ▸ Verification) walk every surface
  # the design names.

  KanbanUITests:
    type: bundle.ui-testing
    platform: macOS
    sources:
      # The verification documents live with the tests they belong to (10-accessibility.md
      # ▸ Verification: "A manual VoiceOver smoke script lives with the test plan"), so they are
      # listed in the project — visible where the suite is — but with no build phase: they are
      # documentation, not resources the bundle should carry. `EndToEndVerification.md` is the same
      # arrangement for the golden-flow, fail-fast and performance suites: the run command, the
      # prerequisites, and the flows that stayed manual.
      - path: KanbanUITests
        excludes:
          - "**/*.md"
      - path: KanbanUITests/AccessibilityVerification.md
        buildPhase: none
      - path: KanbanUITests/EndToEndVerification.md
        buildPhase: none
    dependencies:
      - target: Kanban
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.KanbanUITests
        GENERATE_INFOPLIST_FILE: true
        SWIFT_STRICT_CONCURRENCY: complete

schemes:
  # `xcodebuild … -scheme Kanban` is the established command for this repo, and it now means the
  # only app there is.
  Kanban:
    build:
      targets:
        Kanban: all
    run:
      config: Debug
      # StoreKit Testing in Xcode (12-editions.md ▸ Distribution): a ⌘R run resolves
      # `dev.rzen.indie.kanban.pro.monthly` against the local `Configuration.storekit` instead of
      # against the App Store, so the Settings Pro section shows a price and its purchase flow
      # completes on a machine with no App Store Connect product and no sandbox account.
      #
      # It changes nothing about a build or an archive — it is a *run action* setting, so `xcodebuild
      # build`, `xcodebuild test` and `scripts/release.sh` are untouched, and a shipped app resolves
      # the real product or reports that it cannot reach the App Store.
      storeKitConfiguration: Configuration.storekit
    test:
      config: Debug
      gatherCoverageData: false
      targets:
        - KanbanTests
        - KanbanUITests
    profile:
      config: Release
    analyze:
      config: Debug
    archive:
      config: Release
