Add CI with oxlint and oxfmt - #2
Merged
rin2yh merged 18 commits intoJul 20, 2026
Merged
Conversation
Introduce oxc-based linting (oxlint) and formatting (oxfmt) as the project's lint/format toolchain, pinned to exact versions to match the repo's supply-chain hardening. Type policy enforced via oxlint beyond the correctness defaults: - `any` is banned (typescript/no-explicit-any). - `unknown` is banned as a type (typescript/no-restricted-types), except at the untrusted-input boundary (src/index.ts, which parses the DISCORD_WEBHOOK_MAP JSON) and in test files (partial-mock double casts), via config overrides. buildDiscordPayload previously returned `unknown`; it now returns a concrete DiscordWebhookPayload type. The rest of the codebase is reformatted with oxfmt so `oxfmt --check` is clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
CI runs on pushes to main and on pull requests. It installs the mise-pinned toolchain, then runs oxfmt --check, oxlint, tsc --noEmit, and vitest — the same as `bun run check` locally. README documents the new scripts, the CI pipeline, and the any/unknown policy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Reconcile with the rebased PR #1 base (test helpers moved to src/test/fixtures.ts, comments trimmed, README condensed). Resolutions: - discord.ts keeps the concrete DiscordWebhookPayload return type on top of PR #1's trimmed style. - oxlint unknown-override path updated to src/test/fixtures.ts. - README merged: kept PR #1's condensed prose, kept the CI/lint/format additions. - Reformatted with oxfmt so `oxfmt --check` stays clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Split the single check job into two jobs named `lint` (oxfmt --check, oxlint, tsc --noEmit) and `test` (vitest) so they run in parallel and report independently. Bump and pin third-party actions to commit SHAs (version in a trailing comment) for supply-chain safety: - actions/checkout v4 -> v7.0.0 (9c091bb) - jdx/mise-action v2 -> v4.2.0 (e6a8b39) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Remove the CI workflow trigger/job writeup from the README and keep the lint/format policy under a "Lint & format" heading. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Drop the file-level oxlint overrides that disabled no-restricted-types for src/index.ts and test files. Instead allow `unknown` at its two genuine sites with `// oxlint-disable-next-line typescript/no-restricted-types` plus a reason, so the ban stays in force everywhere else in those files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Build the ForwardableEmailMessage mock as a fully typed object literal (vi.fn() members satisfy the interface signatures), removing the `as unknown as` double cast. `unknown` now appears only at the JSON.parse boundary in src/index.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Drop the lint/format section and script lines from the README, and remove the redundant tool name in parentheses from CI step names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Remove the toolchain/install explanation comments from the workflow (CI just carries the --frozen-lockfile flag) and shorten the JSON-parse boundary comment in src/index.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Remove the fmt:check and lint:fix scripts; pass the flag directly instead (`bun run fmt --check`, `bun run lint --fix`). CI's format step and the aggregate `check` script now use `bun run fmt --check`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Set timeout-minutes: 10 on both CI jobs, and remove the aggregate `check` script (CI runs the steps individually and nothing else referenced it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Use oxlint-disable-line as a trailing comment instead of oxlint-disable-next-line on the line above. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
- discord.test.ts: drop the local Embed interface and the cast; rely on buildDiscordPayload's now-concrete DiscordWebhookPayload return type. - .oxlintrc.json: fix the rule message to reference oxlint-disable-line, matching the actual usage in src/index.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Take PR #1's refactored source and tests as canonical (typed Discord payload, private internals, reorganized tests, spyFetch helpers). Re-apply this branch's CI policy on top: - src/index.ts: per-line disable for the JSON.parse boundary `unknown`. - src/test/fixtures.ts: type the message mock instead of `as unknown as`. - src/discord.test.ts: per-line disables for the two genuine test-only `unknown` uses (parsed JSON return, table expected value). Reformatted with oxfmt; oxlint/typecheck/tests all pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
|
どこまで CI ガチガチにするかですが、
とかで CI 実装を固めておくのはよいかもなーって思いました 👀 |
rin2yh
marked this pull request as ready for review
July 14, 2026 09:57
Contributor
Author
|
全然ありですねー! |
Add a separate gha-ci workflow that runs zizmor against the Actions workflows, triggered only on changes under .github/workflows/** and .github/actions/**. Set persist-credentials: false on the checkout steps in ci.yml (jobs only read code and run tools) — this clears zizmor's artipacked findings, and both workflows now audit clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Drop the push trigger: the workflow audit is not a code gate, so PR-time is sufficient. Still scoped to changes under .github/workflows/** and .github/actions/**. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
Contributor
Author
|
@otakakot pipxを必要とするpython製なのはあまり好みではありませんが、ghaのコンテナにしか入らないのでよしとしてます。 |
otakakot
reviewed
Jul 14, 2026
Switch the gha-ci zizmor step to the official SHA-pinned action (per review suggestion), replacing the manual pipx install + run. Pin the zizmor version to 1.27.0 and disable SARIF upload (advanced-security: false) since the repo has no code scanning — the job fails directly on findings instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
zizmor-action v0.5.7 resolves the version from a bundled digest file and does not know zizmor 1.27.0 (released after the action), which failed with "Unknown version". Rely on the action's default (latest known to v0.5.7); the action is SHA-pinned, so that resolution stays deterministic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GKWrRcDKcg13Xqv5qrr1V
rin2yh
merged commit Jul 20, 2026
a0bd25a
into
claude/email-discord-webhook-worker-am5f2q
3 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
PR #1 のブランチから切って、CI を導入する。 oxc 系の oxlint / oxfmt を採用。
lint/testの2ジョブで実行mainへの push と全 PR でトリガーanyは全面禁止、unknownは基盤(信頼境界)のみ許可設計判断
anyは禁止、unknownは「基盤のみ」許可anyは型チェックを無効化するためtypescript/no-explicit-anyで全面禁止unknownは素通しを避け、外部入力をパースするsrc/index.tsとテスト(部分モックのas unknown as)のみoverridesで許可レビュー観点
補足
コードがない状態で導入してもルールの良さや動作確認がしづらいため、実装してから導入。