Skip to content

Updates from brightdigit.com - #129

Merged
leogdion merged 5 commits into
v1.0.0from
brightdigit-com-260621
Jul 22, 2026
Merged

leogdion merged 5 commits into
v1.0.0from
brightdigit-com-260621

Conversation

@leogdion

Copy link
Copy Markdown
Member

Draft PR to sync the git-subrepo tracking branch into the default branch.

Opened as part of the brightdigit.com monorepo subrepo maintenance sweep (branch brightdigit-com-260717 batch). Contains the changes pushed from the monorepo via git subrepo push.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2911d23-0c0e-4fbb-b6d0-313d737db829

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brightdigit-com-260621

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@claude

claude Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Summary

This is a large (169 files, +1498/-2232) subrepo-sync PR pulling changes from BrightDigit's monorepo into SyndiKit's main. The overwhelming majority of the diff is mechanical: license-header curly-quote → straight-quote normalization (touches nearly every Sources//Tests/ file) and explicit internal/private ACL annotations to satisfy SwiftLint. I did not find any functional changes to the RSS/Atom/JSONFeed/WordPress decoding logic itself — the library's actual behavior appears unchanged. The substantive changes are all in tooling/CI/build config. A few of those are worth a second look before merging.

Potential issues

  1. Package.swift raises the minimum macOS deployment target from .v10_15 to .v13 (iOS/watchOS/tvOS minimums unchanged). This is a breaking change for any consumer still targeting macOS < 13 and should be called out in release notes / warrant a semver-major bump. Worth confirming this is intentional and not an accidental side effect of the sync.

  2. CI test coverage across Swift versions has narrowed. The old syndikit.yml ran the full test suite across a Swift 5.10–6.3 / Ubuntu noble+jammy matrix. The new SyndiKit.yml runs the full suite only on the nightly-6.4.x-noble container; the new swift-source-compat.yml covers Swift 5.10–6.3 but only with swift build --disable-sandbox --configuration release (build-only, no swift test). So actual test execution now happens on a single (nightly/prerelease) Swift toolchain. That's a reasonable tradeoff if intentional (matches the "BrightDigit shared CI template" comment), but it does mean regressions specific to a stable Swift version's test behavior could slip through between the compat-suite build check and the 6.4-nightly test run.

  3. Self-hosted macOS runners are wired to the pull_request trigger (build-macos, build-macos-platforms use runs-on: [self-hosted, macOS] and are gated only by needs: configure/if: !contains(...,'ci skip'), not by fork/author checks). For a public repo, GitHub's own guidance warns against exposing self-hosted runners to pull_request from forks, since a malicious PR can run arbitrary code on that infrastructure. Worth confirming org-level protections (e.g., "require approval for first-time/outside contributors") are enabled, since nothing in the workflow itself restricts this.

  4. Minor doc/config drift: CLAUDE.md's "Naming Conventions" section still says iTunesDuration, iTunesEpisode, iTunesOwner, iTunesImage are "excluded in SwiftLint" (implying a global config exclusion). The updated .swiftlint.yml actually removed the type_name/file_name global exclusions for these types in favor of per-file // swiftlint:disable type_name / // swiftlint:enable type_name comments (e.g. iTunesDuration.swift). The behavior is preserved, but the CLAUDE.md wording is now slightly inaccurate about the mechanism.

Positive notes

  • Nice, low-risk hardening in Tests/SyndiKitXCTests/RSSCodedTests.swift: several force-unwrapped URL(strict:...)! calls were replaced with try XCTUnwrap(URL(strict:...)), which gives a proper test failure instead of a crash if the URL ever fails to parse.
  • The Mint → mise tooling migration (Mintfile removed, .mise.toml added) is clean and consistently threaded through Scripts/lint.sh, CLAUDE.md, and the workflow files.
  • Scripts/lint.sh's error handling was simplified sensibly: it now always accumulates failures into ERRORS and reports/exits at the end rather than stopping at the first failure under set -e, which should make local/CI lint runs more informative (see-all-errors-at-once) — worth double-checking this doesn't mask an early fatal error (e.g., mise install failing) that later steps depend on, since the script keeps going regardless.
  • The DocC/Netlify/Apache local-hosting scaffolding (Dockerfile, Scripts/httpd.conf, Scripts/docc.sh, .htaccess, netlify.toml) was cleanly removed in favor of Swift Package Index-hosted docs, and CLAUDE.md was updated to match.
  • .swiftlint.yml gained a good custom rule (no_unchecked_sendable) banning @unchecked Sendable, which pushes toward proper strict-concurrency conformance — a good move for a library building against Swift 6.4.

Test coverage

No new tests were added or removed, and none needed to be — the diff has no observable behavior changes in the library itself. Given the CI matrix changes above, it'd be worth confirming the swift-source-compat.yml build-only checks are sufficient for catching version-specific regressions, since they don't run the test suite.

Overall this looks like a safe, mostly-mechanical merge; the main things worth a maintainer's explicit sign-off are the macOS 13 minimum deployment target bump and the self-hosted-runner-on-pull_request exposure.

@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Summary

This PR is an automated git-subrepo sync pulling ~5 months of tooling/infra changes from the brightdigit.com monorepo into SyndiKit. It touches 169 files but is almost entirely mechanical:

  • License-header quote normalization (" instead of curly “…”) across nearly every Sources//Tests/ file
  • case let .x(y) → case .x(let y) restyling, driven by the new UseLetInEveryBoundCaseVariable swift-format rule
  • CI overhaul: syndikit.yml (380 lines) replaced by a shared SyndiKit.yml template plus three new standalone workflows (check-unsafe-flags.yml, swift-source-compat.yml, cleanup-caches.yml)
  • Tooling migration from Mint → mise (.mise.toml added, Mintfile removed)
  • Removal of dead docs infra (Dockerfile, Scripts/docc.sh, Scripts/httpd.conf, netlify.toml, project.yml, Scripts/gh-md-toc) now that docs are served via Swift Package Index
  • 3 new test files (EntryIDTests, MediaPropertiesNilTests, SiteCollectionDirectoryBuilderTests) using the new Swift Testing framework, plus a SyndiKitTests/SyndiKitXCTests split
  • No changes to the actual RSS/Atom/JSONFeed decoding logic beyond the cosmetic pattern-matching restyle

Overall this looks safe to merge as routine subrepo maintenance. A few things worth a look before merging:

1. CLAUDE.md is now out of sync with .swiftlint.yml

.swiftlint.yml loosens several thresholds in this PR:

  • cyclomatic_complexity: error 9 → 12
  • function_body_length: warning/error 30/50 → 50/76
  • line_length: 90/90 → 108/200
  • file_length error: 550 → 300 (tightened, opposite direction)

But CLAUDE.md's "SwiftLint Configuration" section (lines 134-137) still documents the old numbers (Max 6 (warning), 9 (error) for complexity, 90 characters (strict) for line length, etc.) — this section wasn't touched by the PR even though the CI/CD and linting-tool sections were updated. Since CLAUDE.md instructs future contributors (and Claude Code) on style limits, it'd be worth updating those four bullet points to match the new .swiftlint.yml values so the doc doesn't mislead.

2. Package.swift: macOS deployment target bump .v10_15 → .v13

This raises the minimum supported macOS version substantially (10.15 → 13). It's a legitimate move (matches the monorepo's newer toolchain baseline), but it's a source-breaking change for any consumer still targeting macOS 10.15–12. Worth confirming this is intentional and called out in release notes / treated as a semver-major bump, since nothing in the PR description mentions it.

3. Scripts/lint.sh: set -e removed, error handling changed

The script now always captures each command's exit status into $ERRORS and exits 1 at the end if any occurred, replacing the old set -e-based / STRICT-only accumulation. This looks like an intentional improvement (avoids silently short-circuiting when one step fails, still respects LINT_MODE=NONE/STRICT), but the default (non-NONE, non-STRICT) mode will now exit non-zero if any underlying command fails outright — previously it wouldn't fail the process for non-strict runs (only warnings were shown). If that mode is used anywhere as a "don't fail the build" step, worth double-checking the new exit behavior doesn't break it.

4. .swift-format stricter rules enabled

NeverForceUnwrap, NeverUseForceTry, NeverUseImplicitlyUnwrappedOptionals, and ValidateDocumentationComments all flip from false/unset to true. These are good defensive-coding rules, but if any existing source uses !/try!/IUO that wasn't caught before, swift-format lint --strict in CI will now fail on it. Worth a swift build + ./Scripts/lint.sh run (with LINT_MODE=STRICT) locally to confirm the full source tree is already clean under the new config before merging — I didn't see any actual force-unwrap/force-try removals in the diff, so this relies on the pre-existing code already being compliant.

Nitpicks

  • Scripts/header.sh now skips a Generated/ directory that doesn't appear to exist anywhere in this repo — harmless, just dead logic carried over from the monorepo template.
  • .dockerignore is retained even though the Dockerfile it presumably supported was deleted in this same PR — worth double-checking it isn't now orphaned.

Test coverage

The three new test files are a nice addition (EntryID branch/round-trip coverage, media-properties nil-handling, site-collection-directory-builder). No regressions spotted in existing test logic — diffs there are limited to header/style churn.

Security

No concerns: all changes are build/lint/CI/test tooling plus cosmetic source restyling; no new external inputs, dependencies, or network/file-I/O paths were introduced.

@codecov

codecov Bot commented Jul 18, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.36%. Comparing base (8259ad5) to head (05e3584).

Additional details and impacted files
@@            Coverage Diff             @@
##           v1.0.0     #129      +/-   ##
==========================================
+ Coverage   78.30%   78.36%   +0.06%     
==========================================
  Files          74       74              
  Lines        1553     1553              
==========================================
+ Hits         1216     1217       +1     
+ Misses        337      336       -1     
Flag Coverage Δ
macos 78.30% <ø> (ø)
noble 78.36% <ø> (+0.06%) ⬆️
spm 78.30% <ø> (ø)
swift-6.4 78.36% <ø> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review: PR #129 — Sync subrepo branch brightdigit-com-260621

This is a large vendoring/sync PR from the monorepo (mostly header-format normalization + CI/lint tooling migration to mise, plus a handful of genuine source changes: file splits for one_declaration_per_file, new test coverage, and a couple of dependency/platform bumps). Overall the mechanical parts (curly-quote to straight-quote, case let .x(y) to case .x(let y), file splits) look clean and low-risk. A few things worth a look before merging:

1. Package.swift platform bump isn't reflected in the docs (correctness)

Package.swift now sets .macOS(.v13) (was .macOS(.v10_15)), but Sources/SyndiKit/SyndiKit.docc/SyndiKit.md still advertises:

- iOS 13 / watchOS 6 / tvOS 13 / macOS 10.15 or later deployment targets

This is the doc that ships to Swift Package Index, so consumers will be told the wrong minimum macOS version (10.15 vs. the actual 13). Worth updating the DocC catalog (and double-checking CLAUDE.md) to match, and worth calling out in the PR description since raising the deployment target is a breaking change for anyone on macOS 10.15-12.

2. Scripts/lint.sh default mode now hard-fails, contradicting CLAUDE.md (behavior change)

CLAUDE.md still documents:

- NONE: Skip linting entirely
- STRICT: Fail on any linting errors
- Default: Run linting with warnings

But in the rewritten script, run_command now unconditionally does "$@" || ERRORS=$((ERRORS + 1)) (previously this counting only happened when LINT_MODE == STRICT), and the script exits 1 at the end if $ERRORS -gt 0 regardless of mode. Since set -e was also removed, the only thing standing between "default mode" and a hard failure was the old STRICT-only counting - that's gone now. So running ./Scripts/lint.sh locally with no LINT_MODE set (or any value other than NONE) will now return a non-zero exit code on lint errors, same as STRICT. If that's intentional, CLAUDE.md should be updated to stop promising "warnings only" for default mode; if not, run_command needs the STRICT-only gate back.

3. Recurring bogus doc comment: "A struct representing an Atom category." (pre-existing, minor)

Not introduced by this PR, but it survived the file-split refactor and is worth a quick cleanup while these files are already being touched: SiteCollectionDirectoryBuilder.swift, PodcastEpisodeProperties.swift, and YouTubeIDProperties.swift all carry a leftover /// A struct representing an Atom category. doc line above unrelated declarations (clearly a copy/paste artifact from doc generation), plus a dangling - SeeAlso: EntryCategory reference that doesn't apply. Since these are public/internal DocC comments that will render on Swift Package Index, it'd be good to strip the incorrect lines.

Good things

  • The curly-quote to straight-quote normalization and case let .x(y) to case .x(let y) rewrite are applied consistently across the whole tree with no missed spots that I found.
  • The SiteCollectionDirectoryBuilder / PodcastEpisodeProperties / YouTubeIDProperties file splits (for the one_declaration_per_file rule) look mechanically correct — types and their doc comments moved intact, no dangling references.
  • Good new test coverage added for previously-uncovered branches: EntryID (all four cases + Codable), SiteCollectionDirectoryBuilder, PodcastEpisodeProperties.init?(rssItem:) nil path, YouTubeIDProperties.init?(entry:) nil path.
  • The mise-based CI rewrite (SyndiKit.yml, .github/actions/setup-tools) is clearly commented and explains why for each nonstandard choice (e.g. the pinned swift-coverage-action SHA, ENABLE_WASM/ENABLE_WATCHOS gating), which makes it easy to audit later.
  • The swiftlint:disable inclusive_language around webMaster in RSSChannel.swift is scoped tightly and justified with a comment referencing the RSS 2.0 spec constraint — good practice for an intentional exception.

Nothing here looks blocking on its own, but #1 and #2 are real inconsistencies between documented behavior and actual behavior that are easy to miss in a diff this size, so flagging them explicitly.

@leogdion
leogdion changed the base branch from main to v1.0.0 July 21, 2026 21:33
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review

This is a CI/tooling-only sync from the brightdigit.com monorepo — no Swift source under Sources/ or Tests/ changes, so the usual code-quality/test-coverage checklist mostly doesn't apply. Focused on the CI workflow and infra changes instead, since those affect every future PR's signal quality.

Potential bugs / regressions

  1. mise GitHub token and timeout silently dropped (.github/actions/setup-tools/action.yml). The old inline step passed:

    env:
      MISE_HTTP_TIMEOUT: 300s
      MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    The new composite action's jdx/mise-action@v4 call has neither. Composite actions can't reach the secrets context directly — it has to be passed in as an explicit inputs: from the calling workflow and threaded through as env. As written, mise install on a cache miss now hits GitHub's API unauthenticated, which is a much lower rate limit and more likely to flake on GitHub-hosted runners (shared IP pool). Worth re-adding MISE_GITHUB_TOKEN (and probably MISE_HTTP_TIMEOUT) as an input to the composite action.

  2. Stale comment vs. removed watchOS gate (.github/workflows/SyndiKit.yml, build-macos-platforms). The comment block above the job still says:

    The watchOS leg is gated on the ENABLE_WATCHOS repo variable (set 'false' to skip it where the watchOS-27 SDK rejects deps inferring 8.0 — SwiftPM #10188; see brightdigit.com#119).

    but the if: ${{ !(matrix.type == 'watchos' && vars.ENABLE_WATCHOS == 'false') }} condition on the "Build and Test" step was removed. If SwiftPM #10188 isn't actually fixed for every consumer of this template yet, watchOS now runs unconditionally and can break full-matrix for packages that previously opted out via ENABLE_WATCHOS=false. If the gate removal is intentional (issue resolved), please update the comment; if not, the if needs to come back.

  3. Coverage-action fork reverted without addressing the reason it existed (build-ubuntu job). This swaps the pinned brightdigit/swift-coverage-action fork back to unpinned upstream sersoft-gmbh/swift-coverage-action@v5, and drops fail-on-empty-output: true. The removed comment explained the fork was needed because "upstream @v5 can't pair the profdata with the test binary under Swift 6.4's swiftbuild layout (.so + <Name>-test-runner, no .xctest) — issue Update CI for December 2026 #92." If that upstream issue isn't actually fixed, this reintroduces silently-empty/missing coverage uploads on Ubuntu — and fail-on-empty-output being gone means it won't even fail loudly. Worth confirming upstream Update CI for December 2026 #92 is resolved before merging.

Design considerations worth a sanity check

  1. fail-fast: false → true on all three matrix strategies (Ubuntu wasm variants, Windows, macOS platforms). This means one failing leg (e.g. the wasm build) now cancels sibling legs before they report, which reduces the amount of cross-platform signal you get from a single CI run — notably now that visionos was just added to the macOS-platforms matrix alongside ios/watchos/tvos. If this is intentional (to save CI minutes), fine, but it's a real drop in diagnostic visibility per red run.

Minor / cosmetic

  1. .devcontainer/devcontainer.json: image was bumped to swiftlang/swift:nightly-6.4.x-noble but "name": "Swift 6.3" wasn't updated to match.
  2. RELEASE_NOTES.md references "brightdigit-com-260621" as the subrepo branch, but the PR description says this sync is for the "brightdigit-com-260717" batch — looks like stale copy from a template used across syncs.

Other

  • The batch of new .claude/skills/* (grilling, to-tickets, loop-me, handoff, writing-great-skills, etc.) and .claude/agent-notes.md are generic agent-workflow tooling, not SyndiKit-specific. Not a problem per se, just flagging in case syncing all of the monorepo's shared agent tooling into every subrepo isn't intended — worth confirming this is the desired scope for this package's .claude/ directory.
  • .spi.yml's new swift_version: "5.10" matches Package.swift's swift-tools-version:5.10, so that one's consistent — no issue there.

No test coverage feedback since no Swift source changed. No security concerns spotted (secrets usage elsewhere in the workflow looks correct).

@leogdion
leogdion marked this pull request as ready for review July 22, 2026 12:19
@leogdion leogdion changed the title Sync subrepo branch brightdigit-com-260621 Updates from brightdigit.com Jul 22, 2026
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review

This is mostly a CI/infra + tooling sync from the brightdigit.com monorepo (via git subrepo push), touching no Swift source under Sources/ or Tests/. Reviewed the four commits' combined diff against v1.0.0.

Bugs / correctness

  1. swift-source-compat-suite job name lost its per-matrix variable (.github/workflows/SyndiKit.yml). The deleted standalone swift-source-compat.yml used:

    name: Test Swift ${{ matrix.container }} For Source Compatibility Suite

    The inlined version hardcodes it:

    name: Test Swift 6.x For Source Compatibility Suite

    All 5 matrix legs (swift:6.0, 6.1, 6.2, 6.3, nightly 6.4) now show up in the Actions UI/checks list with the identical name, so you can't tell which Swift version failed without opening each run. Worth restoring matrix.container in the name.

  2. lint job's needs: doesn't include the newly-inlined swift-source-compat-suite — it only lists [build-ubuntu, build-macos, build-windows, build-android]. Since source-compat used to live in a fully separate workflow this was "independent" by construction; now that it's folded into the same file, it's easy to assume it participates in the same gating and it silently doesn't. If that's intentional (kept as a non-blocking/independent leg), might be worth a comment saying so; otherwise it should probably be added to needs.

Documentation staleness

  1. RELEASE_NOTES.md only documents the first two commits (self-hosted → hosted runner migration, setup-tools composite action). It doesn't mention the third commit's .claude/skills/* additions or the fourth commit's much larger CI rewrite (multi-version Ubuntu/macOS/Windows/Android matrix, restored source-compat suite). It also says Summary of ... PR #129 ("Sync subrepo branch brightdigit-com-260621" ...) while the PR description references brightdigit-com-260717 — the branch name in RELEASE_NOTES.md does match the actual head ref (brightdigit-com-260621), so the PR description text is the stale one, but either way one of the two summaries is out of date and worth reconciling before merge.

Minor nits

  1. Two android-copy-files: "Data/" matrix entries in SyndiKit.yml (for the 6.3/api-28 and 6.3/api-36 legs) have trailing whitespace after the value.
  2. fail_ci_if_error for the Codecov upload step is inconsistent across jobs: true for build-ubuntu/build-macos, false for build-windows/build-android. If that split is deliberate (e.g. Windows/Android coverage is considered best-effort), a short comment would help; otherwise it looks like an oversight.

Scope observation (not a blocker)

This PR also adds a substantial amount of generic .claude/skills/* tooling (grill-me, handoff, loop-me, research, to-spec, to-tickets, writing-great-skills, plus agent-notes.md — ~675 lines) that isn't specific to SyndiKit's actual domain (RSS/Atom/JSON feed decoding). Given this is a subrepo sync from a shared template, that's presumably intentional org-wide policy rather than something to change here — just flagging in case this particular package wasn't meant to receive the full skill set.

Everything else

  • The CI matrix rework itself (three-tier configure job, folded Ubuntu/macOS/Windows/Android matrices, download-platform flags, coverage handling that skips the known-broken profdata pairing on nightly 6.4 by skipping coverage upload there instead of relying on a custom action fork) looks coherent and well-commented.
  • .spi.yml and CLAUDE.md updates are consistent with the new workflow structure.
  • No Swift source changes, so no test coverage impact; no security concerns spotted (no new secrets handling, GITHUB_TOKEN usage is unchanged/standard for mise-action/Codecov).

@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review: PR #129 — Updates from brightdigit.com

This is a subrepo sync carrying CI/tooling changes plus a batch of .claude/ agent-config files. Since it touches no Swift source, I focused on the CI workflow rework (SyndiKit.yml, setup-tools action) and the doc/config sync.

Potential bugs / regressions

  1. setup-tools composite action drops MISE_GITHUB_TOKEN / MISE_HTTP_TIMEOUT (.github/actions/setup-tools/action.yml).
    The inline step this replaces was:

    - uses: jdx/mise-action@v4
      env:
        MISE_HTTP_TIMEOUT: 300s
        MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        cache: true

    The new composite action's "Install mise tools (cache miss)" step has no env: at all, so mise install now fetches swift-format/SwiftLint/periphery from GitHub unauthenticated. Worth double-checking this wasn't the actual cause of the earlier "Fix remaining subrepo CI failures" commit — if it was GitHub API rate-limiting, this refactor could silently reintroduce it. Also worth noting: composite actions don't get implicit access to the secrets context, so fixing this means adding an explicit inputs: (e.g. github-token) to action.yml and passing ${{ secrets.GITHUB_TOKEN }} from the caller — a plain env: add inside the composite step won't work.

  2. Inconsistent Swift 6.4 coverage handling between Ubuntu and macOS.
    build-ubuntu explicitly skips coverage processing/upload on nightly 6.4 (matrix.swift.version != '6.4'), per the prior comment about the coverage action being unable to pair profdata under Swift 6.4's swiftbuild layout (issue Fix Version Number Mirroring swift-build#92 — that comment got removed along with the pinned fork). But build-macos has no equivalent exclusion, and its xcode-27 leg is Swift 6.4 (nightly) via the same swiftbuild layout, running in the always-on "reduced" tier (not gated behind full-matrix). Combined with fail-on-empty-output: true on the coverage step and fail_ci_if_error: true on the Codecov upload, if the same profdata-pairing bug reproduces on macOS/Xcode 27, this could hard-fail the macOS leg on every ordinary PR rather than just skip coverage as intended on Ubuntu.

  3. fail_ci_if_error flipped false → true for both the Ubuntu and macOS Codecov uploads (Windows/Android keep false). These two legs are in the always-on tier, so any Codecov service hiccup will now hard-fail CI on every PR rather than just warn. Combined with finding Update arm.yml #2, this raises the odds of spurious red CI. Might be intentional (tighten coverage enforcement), but worth confirming given the asymmetry with Windows/Android.

Documentation gap

RELEASE_NOTES.md (added by the "Wave 0 review feedback" commit) only summarizes the first two commits (self-hosted → GitHub-hosted runner migration, setup-tools action). It predates and doesn't mention the much larger CI rework in the last two commits (multi-version Ubuntu/macOS/Windows/Android matrix, restoring swift-source-compat.yml as standalone, devcontainer changes) — it'll read as stale/incomplete for anyone relying on it as the change log for this PR.

Minor nits

  • build-android matrix: two entries have trailing whitespace after android-copy-files: "Data/" (harmless, but worth a pass of formatting if YAML is in scope).
  • Same two entries omit android-run-tests entirely (previously hardcoded false), so it now relies on brightdigit/swift-build@v1's default for an empty input rather than being explicit — probably fine, just less self-documenting than before.
  • .devcontainer/devcontainer.json's base image ping-ponged (swift:6.3 → swiftlang/swift:nightly-6.4.x-noble → back to swift:6.3) across commits 2 and 4, netting to no change — just flagging the churn, not a problem in the final diff.
  • The batch of .claude/skills/* and .claude/agent-notes.md files (plus agents/openai.yaml policy files, which look aimed at a different agent platform) are generic personal/team agent tooling synced from the monorepo, unrelated to SyndiKit itself — worth confirming this scope is intentional for this repo rather than incidental subrepo spillover.

Looks good

  • The three-tier configure matrix (small/full/windows) is well-commented and the semver-branch regex correctly covers PRs into v1.0.0 (this PR's actual base), so full-matrix will run here even though it targets a release branch rather than main.
  • Restoring swift-source-compat.yml as its own workflow (rather than folding it into SyndiKit.yml) is a reasonable call — keeps failure isolation and matches the original file this PR is meant to reconcile with.
  • No secrets, credentials, or unsafe flags introduced; check-unsafe-flags.yml and CodeQL remain untouched.

No test coverage concerns beyond CI itself, since this PR doesn't touch Sources/ or Tests/.

leogdion and others added 5 commits July 22, 2026 12:45
Rebuild SyndiKit.yml around a three-tier configure matrix on GitHub-hosted
runners (no self-hosted): a single folded build-ubuntu across stable Swift
5.10-6.3 + nightly 6.4 (wasm/wasm-embedded on 6.3+6.4 only); macOS SPM on
Swift 6.3 (Xcode 26.4) + 6.4 (Xcode 27 preview runner) with the full Apple
platform matrix in the full tier; Windows and Android covering 6.3 + 6.4; and
a restored source-compat suite. Reduced runs stay lean (noble x 6.3/6.4 +
macOS SPM only).

Devcontainers: default to Swift 6.3, add 6.2/6.3/6.4 (6.4 nightly image),
remove the old 6.1/6.2 nightly folders. Refresh the stale CLAUDE.md CI section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the standalone .github/workflows/swift-source-compat.yml (swift:5.10/
6.0/6.1/6.2/6.3 + nightly-6.4) and drop the in-file source-compat-suite job
from SyndiKit.yml; update CLAUDE.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@leogdion
leogdion force-pushed the brightdigit-com-260621 branch from c9269b4 to 516bb01 Compare July 22, 2026 16:45
@leogdion
leogdion merged commit a20625e into v1.0.0 Jul 22, 2026
9 checks passed
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review: PR #129 — Updates from brightdigit.com

This is a subrepo sync bringing over CI/tooling changes from the brightdigit.com monorepo (Draft → merged into v1.0.0). Scope: a major CI rework (.github/workflows/SyndiKit.yml), a new composite action, .spi.yml/CLAUDE.md doc updates, a new RELEASE_NOTES.md, and a batch of .claude/skills/* files unrelated to SyndiKit itself.

Overview

  • Migrates macOS/Apple-platform CI off the self-hosted runner (/Applications/Xcode-beta.app) onto GitHub-hosted runners (macos-26, xcode-27), and expands the Ubuntu matrix to fold in stable Swift 5.10–6.3 alongside nightly 6.4.
  • Adds Swift 6.3 legs to the Windows and Android jobs (previously 6.4-nightly only), and wires up Codecov upload for Android for the first time.
  • Introduces .github/actions/setup-tools, a reusable composite action wrapping jdx/mise-action with a cache step, replacing the inline mise-action call in lint.
  • CLAUDE.md and RELEASE_NOTES.md are updated/added to document the new CI topology — good practice, keeps docs in sync with the workflow.

Potential issues

  1. Inconsistent fail_ci_if_error across platforms (.github/workflows/SyndiKit.yml:168,222,254,311): Ubuntu and macOS Codecov uploads now set fail_ci_if_error: true, while Windows and Android remain false. This is a behavior change from the prior false on Ubuntu — a transient Codecov outage will now fail Ubuntu/macOS CI runs, not just leave coverage unreported. If this is intentional (stricter enforcement on the primary platforms), fine, but worth confirming since it introduces a new source of CI flakiness distinct from actual build/test failures.

  2. Coverage tooling: dropped SHA-pin, narrowed scope — the old Ubuntu job used brightdigit/swift-coverage-action@<SHA> (a fork), pinned specifically because upstream sersoft-gmbh/swift-coverage-action@v5 couldn't pair profdata with the test binary under Swift 6.4's swiftbuild layout (per the original comment referencing issue Update CI for December 2026 #92). The new job uses upstream @v5 (a mutable tag, not a SHA) but only runs coverage when matrix.swift.version != '6.4' — sidestepping the known-broken case rather than fixing it. This looks like a deliberate, reasonable simplification (coverage is skipped exactly where the fork was needed), but it does trade a SHA pin for a floating tag on a third-party action, which is a minor supply-chain-hygiene step back given the CI doc's general care about pinning elsewhere (e.g. the Windows snapshot SHA callouts).

  3. Trailing whitespace in the Android matrix (android-copy-files: "Data/" entries in the build-android matrix): a couple of lines have trailing spaces after the value. Harmless functionally, but likely to trip a strict YAML/whitespace linter if one is ever added.

  4. Unrelated .claude/skills/* additions bundled into this PR: ~10 new skill files (grilling, handoff, to-spec, to-tickets, writing-great-skills, etc.) have nothing to do with SyndiKit's feed-parsing domain — they're generic Claude Code tooling synced in from the monorepo. Given the PR description explains this is an automated git subrepo push sync, this is presumably expected/accepted practice for this repo, but it does make the diff much noisier to review than the actual CI change it's nominally about. Worth confirming this bundling is intentional policy rather than incidental.

  5. skip-package-resolved: ${{ contains(matrix.swift.version, '5.') }} (build-ubuntu): matches any version string containing "5." — fine for the current matrix values (5.10), but a bit fragile as a substring match rather than an explicit version list/comparison. Low risk given the matrix is hand-maintained, just flagging for future-proofing.

Code quality / style

  • No Swift source changes — this PR is CI/tooling/docs only, so the .swiftlint.yml rules (complexity, file length, etc.) don't apply here.
  • The new composite action (setup-tools/action.yml) is a clean, well-scoped extraction — cache-then-fallback pattern is a reasonable way to speed up the lint job.
  • Workflow comments are well-maintained and updated in lockstep with the logic changes (e.g., the header comment in SyndiKit.yml and the CLAUDE.md CI section both reflect the new tiering) — good adherence to this repo's documentation-parity expectations.

Test coverage

  • N/A for source code (no Sources//Tests/ changes). The CI changes themselves expand what gets tested (more Swift versions, more Android API levels with android-run-tests: true on API 28) which is a net positive for coverage breadth.

Security

  • No secrets are introduced or exposed; CODECOV_TOKEN/GITHUB_TOKEN usage is unchanged in shape.
  • The one supply-chain note is Update arm.yml #2 above (mutable @v5 tag vs. a SHA pin) — low severity, but worth a conscious decision rather than an incidental one.

Overall this is a solid, well-documented CI modernization (self-hosted → hosted runners, broader Swift version matrix) with good doc hygiene. The main things I'd want a maintainer to explicitly confirm are the fail_ci_if_error asymmetry (#1) and whether the coverage-action de-pinning (#2) was deliberate.

🤖 Generated with Claude Code

@claude claude Bot mentioned this pull request Jul 22, 2026
leogdion added a commit that referenced this pull request Jul 23, 2026
* Migrate to Swift 6.4: mise-based lint tooling, rebuilt CI, and source cleanups (#127)

* Migrate lint/style/CI configs in 6 BrightDigit subrepo packages [skip ci]

Apply the issue #54 config migration to the vendored BrightDigit libraries
(SyndiKit, TransistorPublishPlugin, Contribute, ContributeWordPress,
NPMPublishPlugin, YoutubePublishPlugin) using the MistKit/SundialKit library
config variant:

- .swiftlint.yml: strict library ruleset + no_unchecked_sendable custom rule
- .swiftformat -> .swift-format: Apple swift-format JSON
- .mise.toml: swift-format 604 (Swift 6.4-aligned), swiftlint, periphery
- Scripts/lint.sh (mise-based, replaces Mint) + Scripts/header.sh
- CI workflow -> brightdigit/swift-build@v1 (ubuntu + macos) + STRICT lint job
- Remove obsolete .hound.yml

Configs + CI only; source reformatting/headers deferred (matches main repo).
SwiftTube and Spinetail skipped (slated for OpenAPI-generator migration).
Committed in the monorepo only; no git subrepo push performed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: trigger pipeline (config migration)

* packages CI: install curl + cache mise tools in lint job

* CI: test vendored BrightDigit packages via monorepo matrix

Add a `test-packages` matrix job to main.yaml that builds, tests, and lints
the 6 vendored BrightDigit packages in-place. In the monorepo checkout every
sibling already sits at its relative-path location, so each package resolves
with zero dependency reconstruction — replacing the per-package setup-deps CI.

- detect-changes: add `packages` paths-filter + `packages-changed` output
- remove standalone workflows + orphaned setup-deps from the 4 rel-dep
  packages (ContributeWordPress, Transistor, NPM, Youtube); their standalone
  CI was synthetic (relative deps are committed)
- keep SyndiKit + Contribute standalone CIs (genuinely standalone libraries)
- bump all GitHub Actions to latest: checkout v6, cache v5, upload-artifact
  v7, download-artifact v8, dorny/paths-filter v4 (swift-build@v1 unchanged)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Conform v1.0.0 codebase to standardized lint configs

Post-rebase cleanup after replaying the config migration onto v1.0.0:
- Fix swiftlint/swift-format violations surfaced by the stricter
  standardized configs (explicit ACLs, formatting, XCTFail messages,
  XCTUnwrap instead of force-unwraps, doc-comment corrections)
- Inline-disable intentional exceptions in source: iTunes* type names,
  RSS-spec webMaster, @unchecked Sendable fallback, large test fixtures
- Split files violating one_declaration_per_file
- Normalize license headers via Scripts/header.sh (straight quotes)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: refresh DocC catalog for v1.0.0

- Update requirements to match Package.swift (Swift 5.10 / Xcode 15.3,
  iOS 13 / watchOS 6 / tvOS 13 / macOS 10.15 deployment targets)
- Bump install snippet to from: "1.0.0"
- Fix transposed JSONFeed column in the Feedable mapping table
  (siteURL -> homePageUrl, summary -> description)
- Fix invalid Swift in code snippets (Data(contentsOf:) usage,
  missing paren in case pattern)
- Fix typos and stale LICENSE link

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Migrate lint/style/CI configs to BrightDigit template patterns (#54) (#76)

* Phase 4 — OpenAPI & dependency migration (#109)

* SyndiKit CI: use jdx/mise-action for robust lint tool bootstrap

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: add macOS + Windows nightly-6.4 CI legs across all 5 standalone repos

Extend ButtondownKit/Spinetail/SwiftTube/Contribute/SyndiKit standalone CI to
the BrightDigit multi-platform template now that a self-hosted macOS runner with
/Applications/Xcode-beta.app (Swift 6.4) is available:

- build-macos: [self-hosted, macOS] + swift-build xcode=Xcode-beta. Blocking on
  all 5. Contribute & SyndiKit migrated off macos-15; their Ubuntu + lint legs
  migrated swift:6.3-noble -> swiftlang/swift:nightly-6.4.x-noble.
- build-windows: hosted windows-2022/2025, swift.org nightly snapshot
  6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-01-a. Gated to full-matrix runs via a
  single-package configure job. continue-on-error on the OpenAPI repos +
  Contribute (unverified deps); blocking on SyndiKit.
- SyndiKit also gains build-macos-platforms (iOS/watchOS/tvOS on released
  Xcode_26.4 — not nightly 6.4).

WASM + Android deferred: no nightly 6.4 support yet. WASM is a swift-build
limitation (brightdigit/swift-build#115 — no input to override the auto-derived
-RELEASE wasm SDK URL); Android is blocked upstream (no nightly 6.4 SDK). Each
workflow documents re-adding them. Contribute WASM is permanently N/A (Yams on
the Musl/wasm SDK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: wire WASM + Android nightly-6.4 CI legs via swift-build SDK-bundle inputs

Now that swift.org publishes nightly 6.4 SDK bundles on swift-6.4.x-branch and
brightdigit/swift-build#116 adds inputs to install caller-supplied bundles, add:

- build-wasm to ButtondownKit/Spinetail/SwiftTube/SyndiKit (NOT Contribute — Yams
  fails on the Musl/wasm SDK). Uses wasm-sdk-url + wasm-sdk-checksum pointing at the
  swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_wasm artifactbundle, with WASI
  emulation + memory flags.
- build-android to all 5 repos. Uses android-sdk-url + android-sdk-id (+ matching
  android-swift-version) for the swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_android
  artifactbundle via skiptools custom-sdk-url; build-only (android-run-tests: false).

Both legs are full-matrix-gated and continue-on-error: they reference @v1 and are
inert until swift-build#116 is released and the v1 tag moved, after which they
should be confirmed green and promoted to blocking (SyndiKit first). Bump the
snapshot SDK URLs/checksums periodically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: run all Apple-platform suites on self-hosted Xcode-beta (Swift 6.4)

Per the rule that Swift 6.4 builds use the self-hosted runners (the only macOS
Swift 6.4 toolchain is /Applications/Xcode-beta.app = Xcode 27 / Swift 6.4):

- Move SyndiKit + Contribute build-macos-platforms off hosted macos-26/Xcode_26.4
  (which is only Swift 6.2) onto [self-hosted, macOS] + Xcode-beta.
- Add build-macos-platforms (iOS/watchOS/tvOS) to ButtondownKit/Spinetail/SwiftTube
  on the same self-hosted runner — these are swift-tools-version:6.4, so hosted
  released-Xcode runners can't even parse their manifests.

All use the iOS/watchOS/tvOS 27.0 simulator runtimes present on the runner
(iPhone 17 Pro / Apple Watch Ultra 3 (49mm) / Apple TV 4K (3rd generation)),
full-matrix-gated and continue-on-error (simulator-on-nightly is the most fragile
leg; promote once green). lint now needs build-macos-platforms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: give Windows its own (stricter) matrix tier

Three CI tiers instead of two: small set (build-ubuntu/build-macos/lint, always)
< full-matrix (macОS-platforms/wasm/android) < +Windows. configure now emits a
second output, run-windows, equal to full-matrix MINUS PRs into semver branches.
build-windows (the most expensive leg — hosted windows-2022/2025 ×2) gates on
run-windows; the rest keep full-matrix. So PRs into semver branches still exercise
the full non-Windows matrix but skip Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: test against swift-build feature branch + fold build-wasm into build-ubuntu

- Point every brightdigit/swift-build@v1 reference at @sdk-url-checksum-nightly-6.4
  (PR #116) TEMPORARILY so CI exercises the new wasm-sdk-url/android-sdk-url code
  before it ships in @v1. Revert to @v1 once #116 is merged + the v1 tag moved.
- Fold build-wasm into build-ubuntu as a continue-on-error step in the same
  nightly-6.4.x-noble container (one spin-up; runs on every push/PR now, not just
  full-matrix). Removed the standalone build-wasm job from ButtondownKit/Spinetail/
  SwiftTube/SyndiKit (Contribute has no wasm — Yams on Musl/wasm).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: only run push CI on main (drop integration branch from push trigger)

Push events now trigger only on main (+ release tags). Feature/integration
branches like brightdigit-com-260406 get CI through their PRs instead of a
redundant branch-push run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: unify the 5 CI workflows to byte-identical (except name)

- Windows is now blocking everywhere (dropped continue-on-error from build-windows
  in all 5, not just SyndiKit).
- The only per-package functional difference — the wasm step (Contribute can't
  build Yams on wasm) — is externalized to the ENABLE_WASM repo variable:
  `if: ${{ vars.ENABLE_WASM != 'false' }}`. Set ENABLE_WASM=false on Contribute.
- Normalized all comments to a shared template.

Result: the five workflow files are byte-identical except the `name:` line; the
only behavioral knob is each repo's ENABLE_WASM variable. Filed Contribute#10 to
fix Yams-on-wasm and re-enable it there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: remove continue-on-error from all 5 CI workflows

Make the WASM step, the Apple-platforms job (iOS/watchOS/tvOS), and the
Android job blocking across all five subrepos. Tidy the now-stale
continue-on-error comment phrases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: gate watchOS leg on ENABLE_WATCHOS (disable where failing)

watchOS-27 SDK rejects deps that infer an 8.0 deployment target (SwiftPM
#10188, not fixable in-repo). Gate the build-macos-platforms watchOS leg on a
new ENABLE_WATCHOS repo variable (mirrors ENABLE_WASM), keeping the 5 workflows
byte-identical. ENABLE_WATCHOS=false is set on ButtondownKit/SwiftTube/
Contribute/Spinetail; SyndiKit (unaffected) keeps running watchOS.

Tracked in brightdigit.com#119.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: build-ubuntu as a [standard, wasm, wasm-embedded] matrix

Mirror brightdigit/MistKit: the configure job emits ubuntu-type (gated by
ENABLE_WASM), and build-ubuntu fans out over it via fromJSON. Standard ('')
always runs; wasm + wasm-embedded run unless ENABLE_WASM=false (e.g. Yams on
Contribute). Both wasm variants share the nightly-6.4.x SDK bundle. Replaces the
single folded WASM step. Byte-identical across all 5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: make wasm/wasm-embedded legs build-only

The wasm/embedded BUILD passes (OpenAPIURLSession is guarded out on WASI), but
running the suite under WasmKit fails: Foundation resource bundles (test
Fixtures) aren't mounted in the WASI sandbox, and embedded hits OpenAPIRuntime
keypath-demangling limits at runtime. Neither is our bug. Build-only validates
wasm/embedded compilation (the goal); the standard leg still runs the full
suite + coverage. Mirrors the Android leg's build-only stance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add tests for uncovered EntryID/SiteCollection/media-properties branches

Covers the 9 patch-coverage gaps flagged on PR #127:
- EntryID: init(string:)/init?(_:)/description/Codable for all four cases
- SiteCollectionDirectoryBuilder: init() + directory(fromCollection:)
- PodcastEpisodeProperties.init?(rssItem:) nil branch (no enclosure)
- YouTubeIDProperties.init?(entry:) nil branch (non-YouTube Atom entry)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* CI: revert swift-build action to @v1 (temp sdk-url-checksum-nightly-6.4 branch deleted)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Align with BrightDigit v1.0.0 CI template and drop self-hosted DocC cruft

Add the template's auxiliary workflows (check-unsafe-flags, cleanup-caches,
swift-source-compat) and .swift-version. Trim the devcontainer matrix to the
supported set (stable 5.10-6.3, nightly 6.4 only; root pinned to 6.3). Remove
the now-stale Mintfile and the self-hosted DocC / XcodeGen stack (netlify.toml,
Dockerfile, .dockerignore, .htaccess, project.yml, Scripts/docc.sh,
Scripts/httpd.conf, Scripts/gh-md-toc) since docs are hosted via SPI. Refresh
.swiftlint.yml excludes and CLAUDE.md to match the mise-based 6.4 tooling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump github.com/coreoffice/xmlcoder from 0.18.1 to 0.18.2

Bumps [github.com/coreoffice/xmlcoder](https://github.com/CoreOffice/XMLCoder) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/CoreOffice/XMLCoder/releases)
- [Commits](CoreOffice/XMLCoder@0.18.1...0.18.2)

---
updated-dependencies:
- dependency-name: github.com/coreoffice/xmlcoder
  dependency-version: 0.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Updates from brightdigit.com (#129)

* Fix remaining subrepo CI failures

* Cache lint tools and align Publish Ink pin

* Wave 0 review feedback: CI hygiene, docs & agent tooling (#130)

* Restore multi-version CI matrix and refresh devcontainers

Rebuild SyndiKit.yml around a three-tier configure matrix on GitHub-hosted
runners (no self-hosted): a single folded build-ubuntu across stable Swift
5.10-6.3 + nightly 6.4 (wasm/wasm-embedded on 6.3+6.4 only); macOS SPM on
Swift 6.3 (Xcode 26.4) + 6.4 (Xcode 27 preview runner) with the full Apple
platform matrix in the full tier; Windows and Android covering 6.3 + 6.4; and
a restored source-compat suite. Reduced runs stay lean (noble x 6.3/6.4 +
macOS SPM only).

Devcontainers: default to Swift 6.3, add 6.2/6.3/6.4 (6.4 nightly image),
remove the old 6.1/6.2 nightly folders. Refresh the stale CLAUDE.md CI section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Keep swift-source-compat as a separate workflow

Restore the standalone .github/workflows/swift-source-compat.yml (swift:5.10/
6.0/6.1/6.2/6.3 + nightly-6.4) and drop the in-file source-compat-suite job
from SyndiKit.yml; update CLAUDE.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(android): cap API level at 34 and cover Swift 6.3 + 6.4-nightly (#131)

The Swift Android SDK's bundled NDK sysroot for API 36 does not ship
crtbegin_dynamic.o / crtend_android.o, which the Swift toolchain still
asks ld.lld to link. That broke the Android leg of CI at API 36 (see
android/ndk#1391).

Rewrite the build-android matrix as a cross product of {Swift 6.3,
Swift 6.4-nightly} x {API 28, API 34}, moving the nightly's SDK URL and
ID onto the swift entry so the 6.3 rows leave them empty.


Claude-Session: https://claude.ai/code/session_014j6vCW2JwTi3P9Sm6q2q4E

Co-authored-by: Claude <noreply@anthropic.com>

* ci(macos): extract matrix JSON and bump Xcode 26.4 → 26.6

Move macOS CI matrix entries into .github/matrices/ for readability, and bump
Apple platform simulator OS versions to 26.5 on the Xcode 26 legs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix v1.0.0 CI badge: correct workflow filename case and stray ?

The CI badge pointed at `syndikit.yml` (lowercase), but on the v1.0.0
branch the workflow file is `SyndiKit.yml` (PascalCase, matching the
other Wave 0 repos), so the badge rendered "no status". Also drop the
stray `?` in `&?branch=main`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
leogdion added a commit that referenced this pull request Jul 23, 2026
* Migrate to Swift 6.4: mise-based lint tooling, rebuilt CI, and source cleanups (#127)

* Migrate lint/style/CI configs in 6 BrightDigit subrepo packages [skip ci]

Apply the issue #54 config migration to the vendored BrightDigit libraries
(SyndiKit, TransistorPublishPlugin, Contribute, ContributeWordPress,
NPMPublishPlugin, YoutubePublishPlugin) using the MistKit/SundialKit library
config variant:

- .swiftlint.yml: strict library ruleset + no_unchecked_sendable custom rule
- .swiftformat -> .swift-format: Apple swift-format JSON
- .mise.toml: swift-format 604 (Swift 6.4-aligned), swiftlint, periphery
- Scripts/lint.sh (mise-based, replaces Mint) + Scripts/header.sh
- CI workflow -> brightdigit/swift-build@v1 (ubuntu + macos) + STRICT lint job
- Remove obsolete .hound.yml

Configs + CI only; source reformatting/headers deferred (matches main repo).
SwiftTube and Spinetail skipped (slated for OpenAPI-generator migration).
Committed in the monorepo only; no git subrepo push performed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: trigger pipeline (config migration)

* packages CI: install curl + cache mise tools in lint job

* CI: test vendored BrightDigit packages via monorepo matrix

Add a `test-packages` matrix job to main.yaml that builds, tests, and lints
the 6 vendored BrightDigit packages in-place. In the monorepo checkout every
sibling already sits at its relative-path location, so each package resolves
with zero dependency reconstruction — replacing the per-package setup-deps CI.

- detect-changes: add `packages` paths-filter + `packages-changed` output
- remove standalone workflows + orphaned setup-deps from the 4 rel-dep
  packages (ContributeWordPress, Transistor, NPM, Youtube); their standalone
  CI was synthetic (relative deps are committed)
- keep SyndiKit + Contribute standalone CIs (genuinely standalone libraries)
- bump all GitHub Actions to latest: checkout v6, cache v5, upload-artifact
  v7, download-artifact v8, dorny/paths-filter v4 (swift-build@v1 unchanged)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Conform v1.0.0 codebase to standardized lint configs

Post-rebase cleanup after replaying the config migration onto v1.0.0:
- Fix swiftlint/swift-format violations surfaced by the stricter
  standardized configs (explicit ACLs, formatting, XCTFail messages,
  XCTUnwrap instead of force-unwraps, doc-comment corrections)
- Inline-disable intentional exceptions in source: iTunes* type names,
  RSS-spec webMaster, @unchecked Sendable fallback, large test fixtures
- Split files violating one_declaration_per_file
- Normalize license headers via Scripts/header.sh (straight quotes)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: refresh DocC catalog for v1.0.0

- Update requirements to match Package.swift (Swift 5.10 / Xcode 15.3,
  iOS 13 / watchOS 6 / tvOS 13 / macOS 10.15 deployment targets)
- Bump install snippet to from: "1.0.0"
- Fix transposed JSONFeed column in the Feedable mapping table
  (siteURL -> homePageUrl, summary -> description)
- Fix invalid Swift in code snippets (Data(contentsOf:) usage,
  missing paren in case pattern)
- Fix typos and stale LICENSE link

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Migrate lint/style/CI configs to BrightDigit template patterns (#54) (#76)

* Phase 4 — OpenAPI & dependency migration (#109)

* SyndiKit CI: use jdx/mise-action for robust lint tool bootstrap

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: add macOS + Windows nightly-6.4 CI legs across all 5 standalone repos

Extend ButtondownKit/Spinetail/SwiftTube/Contribute/SyndiKit standalone CI to
the BrightDigit multi-platform template now that a self-hosted macOS runner with
/Applications/Xcode-beta.app (Swift 6.4) is available:

- build-macos: [self-hosted, macOS] + swift-build xcode=Xcode-beta. Blocking on
  all 5. Contribute & SyndiKit migrated off macos-15; their Ubuntu + lint legs
  migrated swift:6.3-noble -> swiftlang/swift:nightly-6.4.x-noble.
- build-windows: hosted windows-2022/2025, swift.org nightly snapshot
  6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-01-a. Gated to full-matrix runs via a
  single-package configure job. continue-on-error on the OpenAPI repos +
  Contribute (unverified deps); blocking on SyndiKit.
- SyndiKit also gains build-macos-platforms (iOS/watchOS/tvOS on released
  Xcode_26.4 — not nightly 6.4).

WASM + Android deferred: no nightly 6.4 support yet. WASM is a swift-build
limitation (brightdigit/swift-build#115 — no input to override the auto-derived
-RELEASE wasm SDK URL); Android is blocked upstream (no nightly 6.4 SDK). Each
workflow documents re-adding them. Contribute WASM is permanently N/A (Yams on
the Musl/wasm SDK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: wire WASM + Android nightly-6.4 CI legs via swift-build SDK-bundle inputs

Now that swift.org publishes nightly 6.4 SDK bundles on swift-6.4.x-branch and
brightdigit/swift-build#116 adds inputs to install caller-supplied bundles, add:

- build-wasm to ButtondownKit/Spinetail/SwiftTube/SyndiKit (NOT Contribute — Yams
  fails on the Musl/wasm SDK). Uses wasm-sdk-url + wasm-sdk-checksum pointing at the
  swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_wasm artifactbundle, with WASI
  emulation + memory flags.
- build-android to all 5 repos. Uses android-sdk-url + android-sdk-id (+ matching
  android-swift-version) for the swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_android
  artifactbundle via skiptools custom-sdk-url; build-only (android-run-tests: false).

Both legs are full-matrix-gated and continue-on-error: they reference @v1 and are
inert until swift-build#116 is released and the v1 tag moved, after which they
should be confirmed green and promoted to blocking (SyndiKit first). Bump the
snapshot SDK URLs/checksums periodically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: run all Apple-platform suites on self-hosted Xcode-beta (Swift 6.4)

Per the rule that Swift 6.4 builds use the self-hosted runners (the only macOS
Swift 6.4 toolchain is /Applications/Xcode-beta.app = Xcode 27 / Swift 6.4):

- Move SyndiKit + Contribute build-macos-platforms off hosted macos-26/Xcode_26.4
  (which is only Swift 6.2) onto [self-hosted, macOS] + Xcode-beta.
- Add build-macos-platforms (iOS/watchOS/tvOS) to ButtondownKit/Spinetail/SwiftTube
  on the same self-hosted runner — these are swift-tools-version:6.4, so hosted
  released-Xcode runners can't even parse their manifests.

All use the iOS/watchOS/tvOS 27.0 simulator runtimes present on the runner
(iPhone 17 Pro / Apple Watch Ultra 3 (49mm) / Apple TV 4K (3rd generation)),
full-matrix-gated and continue-on-error (simulator-on-nightly is the most fragile
leg; promote once green). lint now needs build-macos-platforms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: give Windows its own (stricter) matrix tier

Three CI tiers instead of two: small set (build-ubuntu/build-macos/lint, always)
< full-matrix (macОS-platforms/wasm/android) < +Windows. configure now emits a
second output, run-windows, equal to full-matrix MINUS PRs into semver branches.
build-windows (the most expensive leg — hosted windows-2022/2025 ×2) gates on
run-windows; the rest keep full-matrix. So PRs into semver branches still exercise
the full non-Windows matrix but skip Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: test against swift-build feature branch + fold build-wasm into build-ubuntu

- Point every brightdigit/swift-build@v1 reference at @sdk-url-checksum-nightly-6.4
  (PR #116) TEMPORARILY so CI exercises the new wasm-sdk-url/android-sdk-url code
  before it ships in @v1. Revert to @v1 once #116 is merged + the v1 tag moved.
- Fold build-wasm into build-ubuntu as a continue-on-error step in the same
  nightly-6.4.x-noble container (one spin-up; runs on every push/PR now, not just
  full-matrix). Removed the standalone build-wasm job from ButtondownKit/Spinetail/
  SwiftTube/SyndiKit (Contribute has no wasm — Yams on Musl/wasm).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: only run push CI on main (drop integration branch from push trigger)

Push events now trigger only on main (+ release tags). Feature/integration
branches like brightdigit-com-260406 get CI through their PRs instead of a
redundant branch-push run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: unify the 5 CI workflows to byte-identical (except name)

- Windows is now blocking everywhere (dropped continue-on-error from build-windows
  in all 5, not just SyndiKit).
- The only per-package functional difference — the wasm step (Contribute can't
  build Yams on wasm) — is externalized to the ENABLE_WASM repo variable:
  `if: ${{ vars.ENABLE_WASM != 'false' }}`. Set ENABLE_WASM=false on Contribute.
- Normalized all comments to a shared template.

Result: the five workflow files are byte-identical except the `name:` line; the
only behavioral knob is each repo's ENABLE_WASM variable. Filed Contribute#10 to
fix Yams-on-wasm and re-enable it there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: remove continue-on-error from all 5 CI workflows

Make the WASM step, the Apple-platforms job (iOS/watchOS/tvOS), and the
Android job blocking across all five subrepos. Tidy the now-stale
continue-on-error comment phrases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: gate watchOS leg on ENABLE_WATCHOS (disable where failing)

watchOS-27 SDK rejects deps that infer an 8.0 deployment target (SwiftPM
#10188, not fixable in-repo). Gate the build-macos-platforms watchOS leg on a
new ENABLE_WATCHOS repo variable (mirrors ENABLE_WASM), keeping the 5 workflows
byte-identical. ENABLE_WATCHOS=false is set on ButtondownKit/SwiftTube/
Contribute/Spinetail; SyndiKit (unaffected) keeps running watchOS.

Tracked in brightdigit.com#119.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: build-ubuntu as a [standard, wasm, wasm-embedded] matrix

Mirror brightdigit/MistKit: the configure job emits ubuntu-type (gated by
ENABLE_WASM), and build-ubuntu fans out over it via fromJSON. Standard ('')
always runs; wasm + wasm-embedded run unless ENABLE_WASM=false (e.g. Yams on
Contribute). Both wasm variants share the nightly-6.4.x SDK bundle. Replaces the
single folded WASM step. Byte-identical across all 5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: make wasm/wasm-embedded legs build-only

The wasm/embedded BUILD passes (OpenAPIURLSession is guarded out on WASI), but
running the suite under WasmKit fails: Foundation resource bundles (test
Fixtures) aren't mounted in the WASI sandbox, and embedded hits OpenAPIRuntime
keypath-demangling limits at runtime. Neither is our bug. Build-only validates
wasm/embedded compilation (the goal); the standard leg still runs the full
suite + coverage. Mirrors the Android leg's build-only stance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add tests for uncovered EntryID/SiteCollection/media-properties branches

Covers the 9 patch-coverage gaps flagged on PR #127:
- EntryID: init(string:)/init?(_:)/description/Codable for all four cases
- SiteCollectionDirectoryBuilder: init() + directory(fromCollection:)
- PodcastEpisodeProperties.init?(rssItem:) nil branch (no enclosure)
- YouTubeIDProperties.init?(entry:) nil branch (non-YouTube Atom entry)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* CI: revert swift-build action to @v1 (temp sdk-url-checksum-nightly-6.4 branch deleted)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Align with BrightDigit v1.0.0 CI template and drop self-hosted DocC cruft

Add the template's auxiliary workflows (check-unsafe-flags, cleanup-caches,
swift-source-compat) and .swift-version. Trim the devcontainer matrix to the
supported set (stable 5.10-6.3, nightly 6.4 only; root pinned to 6.3). Remove
the now-stale Mintfile and the self-hosted DocC / XcodeGen stack (netlify.toml,
Dockerfile, .dockerignore, .htaccess, project.yml, Scripts/docc.sh,
Scripts/httpd.conf, Scripts/gh-md-toc) since docs are hosted via SPI. Refresh
.swiftlint.yml excludes and CLAUDE.md to match the mise-based 6.4 tooling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump github.com/coreoffice/xmlcoder from 0.18.1 to 0.18.2

Bumps [github.com/coreoffice/xmlcoder](https://github.com/CoreOffice/XMLCoder) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/CoreOffice/XMLCoder/releases)
- [Commits](CoreOffice/XMLCoder@0.18.1...0.18.2)

---
updated-dependencies:
- dependency-name: github.com/coreoffice/xmlcoder
  dependency-version: 0.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Updates from brightdigit.com (#129)

* Fix remaining subrepo CI failures

* Cache lint tools and align Publish Ink pin

* Wave 0 review feedback: CI hygiene, docs & agent tooling (#130)

* Restore multi-version CI matrix and refresh devcontainers

Rebuild SyndiKit.yml around a three-tier configure matrix on GitHub-hosted
runners (no self-hosted): a single folded build-ubuntu across stable Swift
5.10-6.3 + nightly 6.4 (wasm/wasm-embedded on 6.3+6.4 only); macOS SPM on
Swift 6.3 (Xcode 26.4) + 6.4 (Xcode 27 preview runner) with the full Apple
platform matrix in the full tier; Windows and Android covering 6.3 + 6.4; and
a restored source-compat suite. Reduced runs stay lean (noble x 6.3/6.4 +
macOS SPM only).

Devcontainers: default to Swift 6.3, add 6.2/6.3/6.4 (6.4 nightly image),
remove the old 6.1/6.2 nightly folders. Refresh the stale CLAUDE.md CI section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Keep swift-source-compat as a separate workflow

Restore the standalone .github/workflows/swift-source-compat.yml (swift:5.10/
6.0/6.1/6.2/6.3 + nightly-6.4) and drop the in-file source-compat-suite job
from SyndiKit.yml; update CLAUDE.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(android): cap API level at 34 and cover Swift 6.3 + 6.4-nightly (#131)

The Swift Android SDK's bundled NDK sysroot for API 36 does not ship
crtbegin_dynamic.o / crtend_android.o, which the Swift toolchain still
asks ld.lld to link. That broke the Android leg of CI at API 36 (see
android/ndk#1391).

Rewrite the build-android matrix as a cross product of {Swift 6.3,
Swift 6.4-nightly} x {API 28, API 34}, moving the nightly's SDK URL and
ID onto the swift entry so the 6.3 rows leave them empty.


Claude-Session: https://claude.ai/code/session_014j6vCW2JwTi3P9Sm6q2q4E

Co-authored-by: Claude <noreply@anthropic.com>

* ci(macos): extract matrix JSON and bump Xcode 26.4 → 26.6

Move macOS CI matrix entries into .github/matrices/ for readability, and bump
Apple platform simulator OS versions to 26.5 on the Xcode 26 legs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix v1.0.0 CI badge: correct workflow filename case and stray ?

The CI badge pointed at `syndikit.yml` (lowercase), but on the v1.0.0
branch the workflow file is `SyndiKit.yml` (PascalCase, matching the
other Wave 0 repos), so the badge rendered "no status". Also drop the
stray `?` in `&?branch=main`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@leogdion
leogdion deleted the brightdigit-com-260621 branch July 26, 2026 21:21
leogdion added a commit that referenced this pull request Jul 27, 2026
* Migrate to Swift 6.4: mise-based lint tooling, rebuilt CI, and source cleanups (#127)

* Migrate lint/style/CI configs in 6 BrightDigit subrepo packages [skip ci]

Apply the issue #54 config migration to the vendored BrightDigit libraries
(SyndiKit, TransistorPublishPlugin, Contribute, ContributeWordPress,
NPMPublishPlugin, YoutubePublishPlugin) using the MistKit/SundialKit library
config variant:

- .swiftlint.yml: strict library ruleset + no_unchecked_sendable custom rule
- .swiftformat -> .swift-format: Apple swift-format JSON
- .mise.toml: swift-format 604 (Swift 6.4-aligned), swiftlint, periphery
- Scripts/lint.sh (mise-based, replaces Mint) + Scripts/header.sh
- CI workflow -> brightdigit/swift-build@v1 (ubuntu + macos) + STRICT lint job
- Remove obsolete .hound.yml

Configs + CI only; source reformatting/headers deferred (matches main repo).
SwiftTube and Spinetail skipped (slated for OpenAPI-generator migration).
Committed in the monorepo only; no git subrepo push performed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci: trigger pipeline (config migration)

* packages CI: install curl + cache mise tools in lint job

* CI: test vendored BrightDigit packages via monorepo matrix

Add a `test-packages` matrix job to main.yaml that builds, tests, and lints
the 6 vendored BrightDigit packages in-place. In the monorepo checkout every
sibling already sits at its relative-path location, so each package resolves
with zero dependency reconstruction — replacing the per-package setup-deps CI.

- detect-changes: add `packages` paths-filter + `packages-changed` output
- remove standalone workflows + orphaned setup-deps from the 4 rel-dep
  packages (ContributeWordPress, Transistor, NPM, Youtube); their standalone
  CI was synthetic (relative deps are committed)
- keep SyndiKit + Contribute standalone CIs (genuinely standalone libraries)
- bump all GitHub Actions to latest: checkout v6, cache v5, upload-artifact
  v7, download-artifact v8, dorny/paths-filter v4 (swift-build@v1 unchanged)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Conform v1.0.0 codebase to standardized lint configs

Post-rebase cleanup after replaying the config migration onto v1.0.0:
- Fix swiftlint/swift-format violations surfaced by the stricter
  standardized configs (explicit ACLs, formatting, XCTFail messages,
  XCTUnwrap instead of force-unwraps, doc-comment corrections)
- Inline-disable intentional exceptions in source: iTunes* type names,
  RSS-spec webMaster, @unchecked Sendable fallback, large test fixtures
- Split files violating one_declaration_per_file
- Normalize license headers via Scripts/header.sh (straight quotes)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: refresh DocC catalog for v1.0.0

- Update requirements to match Package.swift (Swift 5.10 / Xcode 15.3,
  iOS 13 / watchOS 6 / tvOS 13 / macOS 10.15 deployment targets)
- Bump install snippet to from: "1.0.0"
- Fix transposed JSONFeed column in the Feedable mapping table
  (siteURL -> homePageUrl, summary -> description)
- Fix invalid Swift in code snippets (Data(contentsOf:) usage,
  missing paren in case pattern)
- Fix typos and stale LICENSE link

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Migrate lint/style/CI configs to BrightDigit template patterns (#54) (#76)

* Phase 4 — OpenAPI & dependency migration (#109)

* SyndiKit CI: use jdx/mise-action for robust lint tool bootstrap

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: add macOS + Windows nightly-6.4 CI legs across all 5 standalone repos

Extend ButtondownKit/Spinetail/SwiftTube/Contribute/SyndiKit standalone CI to
the BrightDigit multi-platform template now that a self-hosted macOS runner with
/Applications/Xcode-beta.app (Swift 6.4) is available:

- build-macos: [self-hosted, macOS] + swift-build xcode=Xcode-beta. Blocking on
  all 5. Contribute & SyndiKit migrated off macos-15; their Ubuntu + lint legs
  migrated swift:6.3-noble -> swiftlang/swift:nightly-6.4.x-noble.
- build-windows: hosted windows-2022/2025, swift.org nightly snapshot
  6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-01-a. Gated to full-matrix runs via a
  single-package configure job. continue-on-error on the OpenAPI repos +
  Contribute (unverified deps); blocking on SyndiKit.
- SyndiKit also gains build-macos-platforms (iOS/watchOS/tvOS on released
  Xcode_26.4 — not nightly 6.4).

WASM + Android deferred: no nightly 6.4 support yet. WASM is a swift-build
limitation (brightdigit/swift-build#115 — no input to override the auto-derived
-RELEASE wasm SDK URL); Android is blocked upstream (no nightly 6.4 SDK). Each
workflow documents re-adding them. Contribute WASM is permanently N/A (Yams on
the Musl/wasm SDK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: wire WASM + Android nightly-6.4 CI legs via swift-build SDK-bundle inputs

Now that swift.org publishes nightly 6.4 SDK bundles on swift-6.4.x-branch and
brightdigit/swift-build#116 adds inputs to install caller-supplied bundles, add:

- build-wasm to ButtondownKit/Spinetail/SwiftTube/SyndiKit (NOT Contribute — Yams
  fails on the Musl/wasm SDK). Uses wasm-sdk-url + wasm-sdk-checksum pointing at the
  swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_wasm artifactbundle, with WASI
  emulation + memory flags.
- build-android to all 5 repos. Uses android-sdk-url + android-sdk-id (+ matching
  android-swift-version) for the swift-6.4.x-DEVELOPMENT-SNAPSHOT-2026-06-15-a_android
  artifactbundle via skiptools custom-sdk-url; build-only (android-run-tests: false).

Both legs are full-matrix-gated and continue-on-error: they reference @v1 and are
inert until swift-build#116 is released and the v1 tag moved, after which they
should be confirmed green and promoted to blocking (SyndiKit first). Bump the
snapshot SDK URLs/checksums periodically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: run all Apple-platform suites on self-hosted Xcode-beta (Swift 6.4)

Per the rule that Swift 6.4 builds use the self-hosted runners (the only macOS
Swift 6.4 toolchain is /Applications/Xcode-beta.app = Xcode 27 / Swift 6.4):

- Move SyndiKit + Contribute build-macos-platforms off hosted macos-26/Xcode_26.4
  (which is only Swift 6.2) onto [self-hosted, macOS] + Xcode-beta.
- Add build-macos-platforms (iOS/watchOS/tvOS) to ButtondownKit/Spinetail/SwiftTube
  on the same self-hosted runner — these are swift-tools-version:6.4, so hosted
  released-Xcode runners can't even parse their manifests.

All use the iOS/watchOS/tvOS 27.0 simulator runtimes present on the runner
(iPhone 17 Pro / Apple Watch Ultra 3 (49mm) / Apple TV 4K (3rd generation)),
full-matrix-gated and continue-on-error (simulator-on-nightly is the most fragile
leg; promote once green). lint now needs build-macos-platforms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: give Windows its own (stricter) matrix tier

Three CI tiers instead of two: small set (build-ubuntu/build-macos/lint, always)
< full-matrix (macОS-platforms/wasm/android) < +Windows. configure now emits a
second output, run-windows, equal to full-matrix MINUS PRs into semver branches.
build-windows (the most expensive leg — hosted windows-2022/2025 ×2) gates on
run-windows; the rest keep full-matrix. So PRs into semver branches still exercise
the full non-Windows matrix but skip Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: test against swift-build feature branch + fold build-wasm into build-ubuntu

- Point every brightdigit/swift-build@v1 reference at @sdk-url-checksum-nightly-6.4
  (PR #116) TEMPORARILY so CI exercises the new wasm-sdk-url/android-sdk-url code
  before it ships in @v1. Revert to @v1 once #116 is merged + the v1 tag moved.
- Fold build-wasm into build-ubuntu as a continue-on-error step in the same
  nightly-6.4.x-noble container (one spin-up; runs on every push/PR now, not just
  full-matrix). Removed the standalone build-wasm job from ButtondownKit/Spinetail/
  SwiftTube/SyndiKit (Contribute has no wasm — Yams on Musl/wasm).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: only run push CI on main (drop integration branch from push trigger)

Push events now trigger only on main (+ release tags). Feature/integration
branches like brightdigit-com-260406 get CI through their PRs instead of a
redundant branch-push run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: unify the 5 CI workflows to byte-identical (except name)

- Windows is now blocking everywhere (dropped continue-on-error from build-windows
  in all 5, not just SyndiKit).
- The only per-package functional difference — the wasm step (Contribute can't
  build Yams on wasm) — is externalized to the ENABLE_WASM repo variable:
  `if: ${{ vars.ENABLE_WASM != 'false' }}`. Set ENABLE_WASM=false on Contribute.
- Normalized all comments to a shared template.

Result: the five workflow files are byte-identical except the `name:` line; the
only behavioral knob is each repo's ENABLE_WASM variable. Filed Contribute#10 to
fix Yams-on-wasm and re-enable it there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: remove continue-on-error from all 5 CI workflows

Make the WASM step, the Apple-platforms job (iOS/watchOS/tvOS), and the
Android job blocking across all five subrepos. Tidy the now-stale
continue-on-error comment phrases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: gate watchOS leg on ENABLE_WATCHOS (disable where failing)

watchOS-27 SDK rejects deps that infer an 8.0 deployment target (SwiftPM
new ENABLE_WATCHOS repo variable (mirrors ENABLE_WASM), keeping the 5 workflows
byte-identical. ENABLE_WATCHOS=false is set on ButtondownKit/SwiftTube/
Contribute/Spinetail; SyndiKit (unaffected) keeps running watchOS.

Tracked in brightdigit.com#119.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: build-ubuntu as a [standard, wasm, wasm-embedded] matrix

Mirror brightdigit/MistKit: the configure job emits ubuntu-type (gated by
ENABLE_WASM), and build-ubuntu fans out over it via fromJSON. Standard ('')
always runs; wasm + wasm-embedded run unless ENABLE_WASM=false (e.g. Yams on
Contribute). Both wasm variants share the nightly-6.4.x SDK bundle. Replaces the
single folded WASM step. Byte-identical across all 5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Subrepos: make wasm/wasm-embedded legs build-only

The wasm/embedded BUILD passes (OpenAPIURLSession is guarded out on WASI), but
running the suite under WasmKit fails: Foundation resource bundles (test
Fixtures) aren't mounted in the WASI sandbox, and embedded hits OpenAPIRuntime
keypath-demangling limits at runtime. Neither is our bug. Build-only validates
wasm/embedded compilation (the goal); the standard leg still runs the full
suite + coverage. Mirrors the Android leg's build-only stance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add tests for uncovered EntryID/SiteCollection/media-properties branches

Covers the 9 patch-coverage gaps flagged on PR #127:
- EntryID: init(string:)/init?(_:)/description/Codable for all four cases
- SiteCollectionDirectoryBuilder: init() + directory(fromCollection:)
- PodcastEpisodeProperties.init?(rssItem:) nil branch (no enclosure)
- YouTubeIDProperties.init?(entry:) nil branch (non-YouTube Atom entry)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* CI: revert swift-build action to @v1 (temp sdk-url-checksum-nightly-6.4 branch deleted)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Align with BrightDigit v1.0.0 CI template and drop self-hosted DocC cruft

Add the template's auxiliary workflows (check-unsafe-flags, cleanup-caches,
swift-source-compat) and .swift-version. Trim the devcontainer matrix to the
supported set (stable 5.10-6.3, nightly 6.4 only; root pinned to 6.3). Remove
the now-stale Mintfile and the self-hosted DocC / XcodeGen stack (netlify.toml,
Dockerfile, .dockerignore, .htaccess, project.yml, Scripts/docc.sh,
Scripts/httpd.conf, Scripts/gh-md-toc) since docs are hosted via SPI. Refresh
.swiftlint.yml excludes and CLAUDE.md to match the mise-based 6.4 tooling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump github.com/coreoffice/xmlcoder from 0.18.1 to 0.18.2

Bumps [github.com/coreoffice/xmlcoder](https://github.com/CoreOffice/XMLCoder) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/CoreOffice/XMLCoder/releases)
- [Commits](CoreOffice/XMLCoder@0.18.1...0.18.2)

---
updated-dependencies:
- dependency-name: github.com/coreoffice/xmlcoder
  dependency-version: 0.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Updates from brightdigit.com (#129)

* Fix remaining subrepo CI failures

* Cache lint tools and align Publish Ink pin

* Wave 0 review feedback: CI hygiene, docs & agent tooling (#130)

* Restore multi-version CI matrix and refresh devcontainers

Rebuild SyndiKit.yml around a three-tier configure matrix on GitHub-hosted
runners (no self-hosted): a single folded build-ubuntu across stable Swift
5.10-6.3 + nightly 6.4 (wasm/wasm-embedded on 6.3+6.4 only); macOS SPM on
Swift 6.3 (Xcode 26.4) + 6.4 (Xcode 27 preview runner) with the full Apple
platform matrix in the full tier; Windows and Android covering 6.3 + 6.4; and
a restored source-compat suite. Reduced runs stay lean (noble x 6.3/6.4 +
macOS SPM only).

Devcontainers: default to Swift 6.3, add 6.2/6.3/6.4 (6.4 nightly image),
remove the old 6.1/6.2 nightly folders. Refresh the stale CLAUDE.md CI section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Keep swift-source-compat as a separate workflow

Restore the standalone .github/workflows/swift-source-compat.yml (swift:5.10/
6.0/6.1/6.2/6.3 + nightly-6.4) and drop the in-file source-compat-suite job
from SyndiKit.yml; update CLAUDE.md accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(android): cap API level at 34 and cover Swift 6.3 + 6.4-nightly (#131)

The Swift Android SDK's bundled NDK sysroot for API 36 does not ship
crtbegin_dynamic.o / crtend_android.o, which the Swift toolchain still
asks ld.lld to link. That broke the Android leg of CI at API 36 (see
android/ndk#1391).

Rewrite the build-android matrix as a cross product of {Swift 6.3,
Swift 6.4-nightly} x {API 28, API 34}, moving the nightly's SDK URL and
ID onto the swift entry so the 6.3 rows leave them empty.

Claude-Session: https://claude.ai/code/session_014j6vCW2JwTi3P9Sm6q2q4E

Co-authored-by: Claude <noreply@anthropic.com>

* ci(macos): extract matrix JSON and bump Xcode 26.4 → 26.6

Move macOS CI matrix entries into .github/matrices/ for readability, and bump
Apple platform simulator OS versions to 26.5 on the Xcode 26 legs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix v1.0.0 CI badge: correct workflow filename case and stray ?

The CI badge pointed at `syndikit.yml` (lowercase), but on the v1.0.0
branch the workflow file is `SyndiKit.yml` (PascalCase, matching the
other Wave 0 repos), so the badge rendered "no status". Also drop the
stray `?` in `&?branch=main`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant