| 1 | import Link from "next/link"; |
| 2 | import { buildPageMetadata } from "@/lib/page-meta"; |
| 3 | |
| 4 | export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { |
| 5 | const { locale } = await params; |
| 6 | const isZh = locale === "zh"; |
| 7 | return buildPageMetadata({ |
| 8 | path: "/contribute", |
| 9 | locale, |
| 10 | title: isZh ? "参与贡献 · Codewhale" : "Contribute · Codewhale", |
| 11 | description: isZh |
| 12 | ? "提交 issue、改进翻译和文档、发送 pull request,参与 Codewhale 国际开源社区。" |
| 13 | : "File issues, improve translations and documentation, and send pull requests to the international Codewhale community.", |
| 14 | }); |
| 15 | } |
| 16 | |
| 17 | const stepsEn = [ |
| 18 | { |
| 19 | n: "01", |
| 20 | title: "Choose one clear problem", |
| 21 | body: "Browse open issues, especially good first issue and help wanted. If the behavior is not tracked yet, open an issue with a reproduction before starting a large change.", |
| 22 | cta: { label: "Browse open issues", href: "https://github.com/Hmbown/CodeWhale/issues" }, |
| 23 | }, |
| 24 | { |
| 25 | n: "02", |
| 26 | title: "Fork and create a branch", |
| 27 | body: "Clone your fork and use a short branch name such as fix/provider-timeout or docs/fleet-example. Keep unrelated changes in separate pull requests.", |
| 28 | cta: { label: "Open the repository", href: "https://github.com/Hmbown/CodeWhale" }, |
| 29 | }, |
| 30 | { |
| 31 | n: "03", |
| 32 | title: "Test the behavior you changed", |
| 33 | body: "Run the smallest relevant test first, then formatting and the broader checks required for the part of the repository you touched.", |
| 34 | cta: { label: "Read the contributor guide", href: "https://github.com/Hmbown/CodeWhale/blob/main/CONTRIBUTING.md" }, |
| 35 | }, |
| 36 | { |
| 37 | n: "04", |
| 38 | title: "Explain the result in the PR", |
| 39 | body: "Describe the problem, the reason for the change, the checks you ran, and any remaining risk. Link the issue when one exists.", |
| 40 | cta: { label: "View open pull requests", href: "https://github.com/Hmbown/CodeWhale/pulls" }, |
| 41 | }, |
| 42 | ]; |
| 43 | |
| 44 | const stepsZh = [ |
| 45 | { |
| 46 | n: "01", |
| 47 | title: "选择一个明确的问题", |
| 48 | body: "先浏览 open issues,尤其是 good first issue 和 help wanted。如果问题尚未记录,请在开始大改动前提交带复现步骤的 issue。", |
| 49 | cta: { label: "浏览 open issues", href: "https://github.com/Hmbown/CodeWhale/issues" }, |
| 50 | }, |
| 51 | { |
| 52 | n: "02", |
| 53 | title: "Fork 并创建分支", |
| 54 | body: "克隆你的 fork,并使用简短的分支名,例如 fix/provider-timeout 或 docs/fleet-example。无关修改请拆成不同的 pull request。", |
| 55 | cta: { label: "打开仓库", href: "https://github.com/Hmbown/CodeWhale" }, |
| 56 | }, |
| 57 | { |
| 58 | n: "03", |
| 59 | title: "测试你修改的行为", |
| 60 | body: "先运行最小相关测试,再执行格式检查和你所修改部分需要的更完整检查。", |
| 61 | cta: { label: "阅读贡献指南", href: "https://github.com/Hmbown/CodeWhale/blob/main/CONTRIBUTING.md" }, |
| 62 | }, |
| 63 | { |
| 64 | n: "04", |
| 65 | title: "在 PR 中说明结果", |
| 66 | body: "说明问题、修改原因、已运行的检查和剩余风险;如果已有 issue,请在 PR 中关联。", |
| 67 | cta: { label: "查看 open pull requests", href: "https://github.com/Hmbown/CodeWhale/pulls" }, |
| 68 | }, |
| 69 | ]; |
| 70 | |
| 71 | export default async function ContributePage({ params }: { params: Promise<{ locale: string }> }) { |
| 72 | const { locale } = await params; |
| 73 | const isZh = locale === "zh"; |
| 74 | const steps = isZh ? stepsZh : stepsEn; |
| 75 | |
| 76 | const paths = isZh |
| 77 | ? [ |
| 78 | { |
| 79 | title: "报告 bug 或兼容性问题", |
| 80 | body: "提供系统信息、Codewhale 版本、复现步骤、期望行为和可公开的日志。", |
| 81 | label: "提交 issue", |
| 82 | href: "https://github.com/Hmbown/CodeWhale/issues/new/choose", |
| 83 | }, |
| 84 | { |
| 85 | title: "改进代码或测试", |
| 86 | body: "选择一个边界清楚的问题,提交最小补丁,并用回归测试证明修改后的行为。", |
| 87 | label: "查看待处理 issues", |
| 88 | href: "https://github.com/Hmbown/CodeWhale/issues", |
| 89 | }, |
| 90 | { |
| 91 | title: "改进文档或翻译", |
| 92 | body: "修正不准确的说明、补充实际示例,或帮助完整语言包保持自然且与英文键一致。", |
| 93 | label: "阅读本地化指南", |
| 94 | href: "https://github.com/Hmbown/CodeWhale/blob/main/docs/LOCALIZATION.md", |
| 95 | }, |
| 96 | { |
| 97 | title: "复现和审查现有工作", |
| 98 | body: "验证 issue 或 pull request 在你的平台和提供商上的行为,并分享准确的测试结果。", |
| 99 | label: "浏览 pull requests", |
| 100 | href: "https://github.com/Hmbown/CodeWhale/pulls", |
| 101 | }, |
| 102 | ] |
| 103 | : [ |
| 104 | { |
| 105 | title: "Report a bug or compatibility problem", |
| 106 | body: "Include your system, Codewhale version, reproduction steps, expected behavior, and any logs you can share safely.", |
| 107 | label: "File an issue", |
| 108 | href: "https://github.com/Hmbown/CodeWhale/issues/new/choose", |
| 109 | }, |
| 110 | { |
| 111 | title: "Improve code or tests", |
| 112 | body: "Choose a well-bounded problem, make the smallest useful patch, and add a regression test that proves the changed behavior.", |
| 113 | label: "Browse open issues", |
| 114 | href: "https://github.com/Hmbown/CodeWhale/issues", |
| 115 | }, |
| 116 | { |
| 117 | title: "Improve documentation or translations", |
| 118 | body: "Correct inaccurate guidance, add a practical example, or help a complete language pack stay natural and aligned with the English keys.", |
| 119 | label: "Read the localization guide", |
| 120 | href: "https://github.com/Hmbown/CodeWhale/blob/main/docs/LOCALIZATION.md", |
| 121 | }, |
| 122 | { |
| 123 | title: "Reproduce and review existing work", |
| 124 | body: "Verify an issue or pull request with your platform and provider, then share the exact checks and results.", |
| 125 | label: "Browse pull requests", |
| 126 | href: "https://github.com/Hmbown/CodeWhale/pulls", |
| 127 | }, |
| 128 | ]; |
| 129 | |
| 130 | const reviewNotes = isZh |
| 131 | ? [ |
| 132 | "一个 PR 只解决一个问题,便于测试、审查和保留贡献者署名。", |
| 133 | "新增行为应有测试;修正文档时,请核对实际命令、配置名和当前版本。", |
| 134 | "修改认证、凭据、沙箱、发布流程、品牌或全局提示词前,请先提交 issue 并确认范围。", |
| 135 | "如果维护者需要整理或摘取补丁,原作者仍会在提交、CHANGELOG 和贡献者名单中获得署名。", |
| 136 | ] |
| 137 | : [ |
| 138 | "Keep one problem per pull request so the change is easy to test, review, and credit.", |
| 139 | "Add tests for new behavior. For documentation fixes, verify commands, configuration names, and the current version against the repository.", |
| 140 | "Open an issue before changing authentication, credentials, sandbox policy, release plumbing, branding, or global prompts.", |
| 141 | "If a maintainer needs to adapt or harvest a patch, the original contributor remains credited in the commit, changelog, and contributor list.", |
| 142 | ]; |
| 143 | |
| 144 | return ( |
| 145 | <div className="contribute-page"> |
| 146 | <section className="community-welcome"> |
| 147 | <div className="portal-current" aria-hidden="true" /> |
| 148 | <div className="portal-container community-welcome-inner"> |
| 149 | <div className="eyebrow">{isZh ? "参与国际开源社区" : "Contribute to an international open-source project"}</div> |
| 150 | <h1>{isZh ? "从一个具体的改进开始。" : "Start with one concrete improvement."}</h1> |
| 151 | <p> |
| 152 | {isZh |
| 153 | ? "Codewhale 欢迎来自不同国家、语言、平台和经验水平的贡献者。清楚的 bug 报告、复现结果、文档修正、翻译和小而完整的代码补丁都会直接帮助项目。" |
| 154 | : "Codewhale welcomes contributors across countries, languages, platforms, and experience levels. Clear bug reports, reproduction results, documentation corrections, translations, and small complete patches all move the project forward."} |
| 155 | </p> |
| 156 | <div className="portal-actions"> |
| 157 | <Link href="https://github.com/Hmbown/CodeWhale/issues/new/choose" className="portal-button portal-button-primary"> |
| 158 | {isZh ? "提交 issue" : "File an issue"} |
| 159 | </Link> |
| 160 | <Link href="https://github.com/Hmbown/CodeWhale/pulls" className="portal-button portal-button-secondary"> |
| 161 | {isZh ? "查看 pull requests" : "Browse pull requests"} |
| 162 | </Link> |
| 163 | <Link href="https://github.com/Hmbown/CodeWhale/blob/main/CONTRIBUTING.md" className="portal-button portal-button-secondary"> |
| 164 | {isZh ? "打开完整贡献指南" : "Open the full contributor guide"} |
| 165 | </Link> |
| 166 | </div> |
| 167 | </div> |
| 168 | </section> |
| 169 | |
| 170 | <section className="portal-section"> |
| 171 | <div className="portal-container"> |
| 172 | <div className="portal-docs-heading"> |
| 173 | <div> |
| 174 | <span>{isZh ? "现在就可以参与" : "Ways to help now"}</span> |
| 175 | <h2>{isZh ? "选择适合你的贡献方式。" : "Choose the contribution that fits."}</h2> |
| 176 | </div> |
| 177 | </div> |
| 178 | <div className="contribute-path-grid"> |
| 179 | {paths.map((path) => ( |
| 180 | <article key={path.title}> |
| 181 | <h3>{path.title}</h3> |
| 182 | <p>{path.body}</p> |
| 183 | <Link href={path.href}>{path.label} →</Link> |
| 184 | </article> |
| 185 | ))} |
| 186 | </div> |
| 187 | </div> |
| 188 | </section> |
| 189 | |
| 190 | <section className="portal-section portal-section-muted"> |
| 191 | <div className="portal-container"> |
| 192 | <div className="portal-docs-heading"> |
| 193 | <div> |
| 194 | <span>{isZh ? "Pull request 流程" : "Pull request workflow"}</span> |
| 195 | <h2>{isZh ? "从问题到可审查的补丁。" : "From a problem to a reviewable patch."}</h2> |
| 196 | </div> |
| 197 | </div> |
| 198 | <ol className="contribute-steps"> |
| 199 | {steps.map((step) => ( |
| 200 | <li key={step.n}> |
| 201 | <span>{step.n}</span> |
| 202 | <div> |
| 203 | <h3>{step.title}</h3> |
| 204 | <p>{step.body}</p> |
| 205 | <Link href={step.cta.href}>{step.cta.label} →</Link> |
| 206 | </div> |
| 207 | </li> |
| 208 | ))} |
| 209 | </ol> |
| 210 | </div> |
| 211 | </section> |
| 212 | |
| 213 | <section className="portal-section"> |
| 214 | <div className="portal-container portal-section-grid"> |
| 215 | <div className="portal-section-copy"> |
| 216 | <span>{isZh ? "审查准备" : "Prepare for review"}</span> |
| 217 | <h2>{isZh ? "让修改容易验证。" : "Make the change easy to verify."}</h2> |
| 218 | <p> |
| 219 | {isZh |
| 220 | ? "审查者需要看到问题、修改理由、测试证据和剩余风险。范围越清楚,反馈通常越快。" |
| 221 | : "A reviewer needs the problem, the reason for the change, test evidence, and remaining risk. Clear scope usually leads to clearer feedback."} |
| 222 | </p> |
| 223 | </div> |
| 224 | <ul className="contribute-review-list"> |
| 225 | {reviewNotes.map((note) => <li key={note}>{note}</li>)} |
| 226 | </ul> |
| 227 | </div> |
| 228 | </section> |
| 229 | |
| 230 | <section className="contribute-dev-loop"> |
| 231 | <div className="portal-container portal-section-grid min-w-0"> |
| 232 | <div className="portal-section-copy"> |
| 233 | <span>{isZh ? "本地开发" : "Local development"}</span> |
| 234 | <h2>{isZh ? "构建并运行相关检查。" : "Build and run the relevant checks."}</h2> |
| 235 | <p> |
| 236 | {isZh |
| 237 | ? "仓库使用 stable Rust。先运行你所修改部分的测试,再运行格式检查、Clippy 和完整工作区测试。" |
| 238 | : "The repository uses stable Rust. Run the focused test for your change first, followed by formatting, Clippy, and the workspace suite."} |
| 239 | </p> |
| 240 | </div> |
| 241 | <pre className="code-block"> |
| 242 | {`git clone https://github.com/YOUR_USERNAME/CodeWhale.git |
| 243 | cd CodeWhale |
| 244 | git checkout -b fix/your-change |
| 245 | |
| 246 | cargo build |
| 247 | cargo test -p <owning-crate> --locked |
| 248 | cargo fmt --all -- --check |
| 249 | cargo clippy --workspace --all-targets --all-features --locked -- -D warnings |
| 250 | cargo test --workspace --all-features --locked`} |
| 251 | </pre> |
| 252 | </div> |
| 253 | </section> |
| 254 | </div> |
| 255 | ); |
| 256 | } |
| 257 |