完成项目一键初始化工作流(03-project-init):重构为文件模式生成README/LICENSE/CI配置+里程碑+Issue+分支保护+Release

- README/LICENSE/CONTRIBUTING/.gitlink-ci.yml 生成在仓库内,而非Wiki页面
- 新增里程碑创建步骤、欢迎Issue
- README中文标题(快速开始、环境要求、安装、使用、测试)
- git clone/push免密认证、git作者行内传参
- 修复CRLF换行符、反引号命令替换等问题
- 同步更新PowerShell版本(03-project-init.ps1)
- 更新workflows文档和SKILL菜单
This commit is contained in:
camelliamc 2026-07-10 18:37:19 +08:00
parent 9f0973f80a
commit 3988802e2c
5 changed files with 754 additions and 283 deletions

View File

@ -36,14 +36,14 @@ func Shortcuts() []*common.Shortcut {
Flags: []common.Flag{
{Name: "name", Short: "n", Usage: "Milestone name", Required: true},
{Name: "description", Short: "d", Usage: "Description"},
{Name: "due", Usage: "Due date (YYYY-MM-DD)"},0.
{Name: "due", Usage: "Due date (YYYY-MM-DD)"},
},
Run: func(ctx *common.RuntimeContext) error {
if err := ctx.ResolveOwnerRepo(); err != nil {
return err
}
name, _ := ctx.RequireArg("name", `--name "My Name"`)
body := [string]interface{}{
body := map[string]interface{}{
"title": name,
}
if d := ctx.Arg("description"); d != "" {

View File

@ -1,16 +1,18 @@
# ----------------------------------------------------------------
# ----------------------------------------------------------------
# Scenario 3: One-Click Project Initialization
# Flow: Input description -> Create repo -> README/CONTRIBUTING/CI config ->
# Initial Issues -> Branch protection -> Initial Release
# Flow: Input description -> Create repo -> Generate files (README/LICENSE/
# CONTRIBUTING/CI) -> Push to repo -> Milestones -> Issues ->
# Branch protection -> Initial Release
#
# Commands chained:
# 1. repo +create -- create repository
# 2. wiki +create -- create README wiki page
# 3. wiki +create -- create CONTRIBUTING guide
# 4. wiki +create -- create CI/CD config guide
# 5. issue +create -- create initial issues
# 6. branch +protect -- protect master branch
# 7. release +create -- create initial release
# 2. git clone -- clone the empty repo locally
# 3. file generation -- README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml
# 4. git add/commit/push -- push scaffold files to repo
# 5. milestone +create -- create project milestones
# 6. issue +create -- create initial issues
# 7. branch +protect -- protect default branch
# 8. release +create -- create initial release
# ----------------------------------------------------------------
#Requires -Version 5.1
@ -32,7 +34,7 @@ if ($Help) {
exit 0
}
if (-not $Name) { Log-Err "Name is required (use -Help for usage)"; exit 1 }
if (-not $Name) { Log-Err "Name is required (use -Help for usage)"; exit 1 }
if (-not $Description) { Log-Err "Description is required (use -Help for usage)"; exit 1 }
Check-Auth
@ -52,7 +54,7 @@ Write-Host " Private: $($Private.IsPresent)"
Divider
# -- Step 1: Create Repository --
Log-Step "Creating repository..."
Log-Step "Step 1/8: Creating repository..."
if ($DryRun) {
Log-Warn "[DRY RUN] Would create repository: $Owner/$Name"
} else {
@ -66,123 +68,378 @@ if ($DryRun) {
}
}
# -- Step 2: Create README --
Log-Step "Creating README wiki page..."
Start-Sleep -Seconds 2
$langSection = switch ($Lang) {
"go" {
"### Prerequisites`n- Go 1.21+`n- Git`n`n### Installation`n``````bash`ngit clone https://gitlink.org.cn/$Owner/$Name.git`ncd $Name`ngo mod download`ngo build ./...`n```````n`n### Usage`n``````bash`ngo run main.go`n```````n`n### Testing`n``````bash`ngo test ./...`n``````"
}
"python" {
"### Prerequisites`n- Python 3.9+`n- pip`n`n### Installation`n``````bash`ngit clone https://gitlink.org.cn/$Owner/$Name.git`ncd $Name`npip install -r requirements.txt`n```````n`n### Usage`n``````bash`npython main.py`n```````n`n### Testing`n``````bash`npytest`n``````"
}
"node" {
"### Prerequisites`n- Node.js 18+`n- npm or yarn`n`n### Installation`n``````bash`ngit clone https://gitlink.org.cn/$Owner/$Name.git`ncd $Name`nnpm install`n```````n`n### Usage`n``````bash`nnpm start`n```````n`n### Testing`n``````bash`nnpm test`n``````"
}
"java" {
"### Prerequisites`n- JDK 17+`n- Maven 3.8+`n`n### Installation`n``````bash`ngit clone https://gitlink.org.cn/$Owner/$Name.git`ncd $Name`nmvn clean install`n```````n`n### Usage`n``````bash`nmvn exec:java`n```````n`n### Testing`n``````bash`nmvn test`n``````"
}
default { "" }
# -- Step 2: Clone empty repo --
Log-Step "Step 2/8: Cloning repository..."
$repoUrl = "https://gitlink.org.cn/$Owner/$Name.git"
if ($env:GITLINK_TOKEN) {
$cloneUrl = "https://oauth2:$($env:GITLINK_TOKEN)@gitlink.org.cn/$Owner/$Name.git"
} else {
$cloneUrl = $repoUrl
}
$readmeContent = "# $Name" + "`n`n"
$readmeContent += "$Description" + "`n`n"
$readmeContent += "## Getting Started" + "`n`n"
$readmeContent += $langSection + "`n`n"
$readmeContent += "## Contributing" + "`n`n"
$readmeContent += "See [CONTRIBUTING](./CONTRIBUTING) for guidelines." + "`n`n"
$readmeContent += "## License" + "`n`n"
$readmeContent += "This project is licensed under the MIT License."
$workDir = Join-Path $env:TEMP "gitlink-init-$([System.Guid]::NewGuid().ToString('N').Substring(0, 8))"
if ($DryRun) {
Log-Warn "[DRY RUN] Would create README wiki page"
Log-Warn "[DRY RUN] Would clone: $repoUrl -> $workDir"
} else {
$wikiOk = $false
for ($attempt = 1; $attempt -le 3; $attempt++) {
$wikiResult = Invoke-GL wiki,+create,--owner,$Owner,--repo,$Name,--title,"README",--content,$readmeContent
if ($wikiResult -and (Get-JsonOk ($wikiResult | ConvertFrom-Json))) {
Log-Ok "README created"
$wikiOk = $true
break
git clone $cloneUrl $workDir 2>&1 | Select-Object -Last 1
Log-Ok "Cloned to $workDir"
}
# -- Step 3: Generate project files --
Log-Step "Step 3/8: Generating project scaffold files..."
function Get-ReadmeContent {
$langSection = switch ($Lang) {
"go" {
@"
### 环境要求
- Go 1.21+
- Git
### 安装
```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
go mod download
go build ./...
```
### 使用
```bash
go run main.go
```
### 测试
```bash
go test ./...
```
"@
}
if ($attempt -lt 3) { Start-Sleep -Seconds 2 }
}
if (-not $wikiOk) { Log-Warn "README wiki creation may have failed" }
}
"python" {
@"
### 环境要求
# -- Step 3: Create CONTRIBUTING Guide --
Log-Step "Creating CONTRIBUTING guide..."
- Python 3.9+
- pip
$contribContent = "# Contributing to $Name" + "`n`n"
$contribContent += "Thank you for your interest in contributing!" + "`n`n"
$contribContent += "## How to Contribute" + "`n`n"
$contribContent += "1. Fork the repository" + "`n"
$contribContent += "2. Create a feature branch: ``git checkout -b feature/my-feature```n"
$contribContent += "3. Make your changes" + "`n"
$contribContent += "4. Run tests to ensure everything passes" + "`n"
$contribContent += "5. Commit your changes: ``git commit -m 'feat: add my feature'```n"
$contribContent += "6. Push to your fork: ``git push origin feature/my-feature```n"
$contribContent += "7. Create a Pull Request" + "`n`n"
$contribContent += "## Code Style" + "`n`n"
$contribContent += "- Follow the existing code style" + "`n"
$contribContent += "- Write meaningful commit messages" + "`n"
$contribContent += "- Add tests for new features" + "`n"
$contribContent += "- Update documentation as needed" + "`n`n"
$contribContent += "## Reporting Issues" + "`n`n"
$contribContent += "- Use the issue tracker" + "`n"
$contribContent += "- Include reproduction steps" + "`n"
$contribContent += "- Include environment details"
### 安装
if ($DryRun) {
Log-Warn "[DRY RUN] Would create CONTRIBUTING wiki page"
} else {
$wikiOk = $false
for ($attempt = 1; $attempt -le 3; $attempt++) {
$wikiContrib = Invoke-GL wiki,+create,--owner,$Owner,--repo,$Name,--title,"CONTRIBUTING",--content,$contribContent
if ($wikiContrib -and (Get-JsonOk ($wikiContrib | ConvertFrom-Json))) {
Log-Ok "CONTRIBUTING guide created"
$wikiOk = $true
break
```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
pip install -r requirements.txt
```
### 使用
```bash
python main.py
```
### 测试
```bash
pytest
```
"@
}
if ($attempt -lt 3) { Start-Sleep -Seconds 2 }
"node" {
@"
### 环境要求
- Node.js 18+
- npm or yarn
### 安装
```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
npm install
```
### 使用
```bash
npm start
```
### 测试
```bash
npm test
```
"@
}
"java" {
@"
### 环境要求
- JDK 17+
- Maven 3.8+
### 安装
```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
mvn clean install
```
### 使用
```bash
mvn exec:java
```
### 测试
```bash
mvn test
```
"@
}
default { "" }
}
if (-not $wikiOk) { Log-Warn "CONTRIBUTING wiki creation may have failed" }
return @"
# $Name
$Description
## 快速开始
$langSection
## 贡献指南
详见 [CONTRIBUTING](./CONTRIBUTING.md)
## 许可证
本项目基于 MIT 许可证开源 详见 [LICENSE](./LICENSE)
"@
}
# -- Step 4: Create CI Config Guide --
Log-Step "Creating CI/CD configuration guide..."
function Get-LicenseContent {
$year = (Get-Date).Year
return @"
MIT License
$ciContent = "# CI/CD Configuration" + "`n`n"
$ciContent += "## GitLink CI Setup" + "`n`n"
$ciContent += "This project uses GitLink CI for continuous integration." + "`n`n"
$ciContent += "### Pipeline Stages" + "`n`n"
$ciContent += "1. **Test**: Run unit tests" + "`n"
$ciContent += "2. **Build**: Build the project" + "`n"
$ciContent += "3. **Deploy**: Deploy to staging (master branch only)" + "`n`n"
$ciContent += "### Configuration" + "`n`n"
$ciContent += "Create a ``.gitlink-ci.yml`` file in the repository root."
Copyright (c) $year $Owner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"@
}
function Get-ContributingContent {
return @"
# Contributing to $Name
Thank you for your interest in contributing!
## How to Contribute
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-feature`
3. Make your changes
4. Run tests to ensure everything passes
5. Commit your changes: `git commit -m 'feat: add my feature'`
6. Push to your fork: `git push origin feature/my-feature`
7. Create a Pull Request
## Code Style
- Follow the existing code style
- Write meaningful commit messages following [Conventional Commits](https://www.conventionalcommits.org/)
- Add tests for new features
- Update documentation as needed
## Reporting Issues
- Use the [issue tracker](https://gitlink.org.cn/$Owner/$Name/issues)
- Include steps to reproduce
- Include environment details (OS, language version, etc.)
## Code of Conduct
Please be respectful and constructive in all interactions.
"@
}
function Get-CIConfigContent {
switch ($Lang) {
"go" {
return @"
image: golang:1.21
stages:
- test
- build
test:
stage: test
script:
- go mod download
- go test ./... -v -cover
build:
stage: build
script:
- go build ./...
"@
}
"python" {
return @"
image: python:3.9
stages:
- test
- lint
test:
stage: test
script:
- pip install -r requirements.txt
- pytest -v --cov
lint:
stage: lint
script:
- pip install flake8
- flake8 .
"@
}
"node" {
return @"
image: node:18
stages:
- test
- build
test:
stage: test
script:
- npm ci
- npm test -- --coverage
build:
stage: build
script:
- npm ci
- npm run build
"@
}
"java" {
return @"
image: maven:3.8-openjdk-17
stages:
- test
- build
test:
stage: test
script:
- mvn test
build:
stage: build
script:
- mvn package -DskipTests
"@
}
default {
return "# TODO: configure CI/CD pipeline for $Lang"
}
}
}
if ($DryRun) {
Log-Warn "[DRY RUN] Would create CI/CD configuration wiki page"
Log-Warn "[DRY RUN] Would generate: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
} else {
Invoke-GL wiki,+create,--owner,$Owner,--repo,$Name,--title,"CI/CD Configuration",--content,$ciContent | Out-Null
Log-Ok "CI/CD configuration guide created"
$utf8 = [System.Text.UTF8Encoding]::new($false)
[System.IO.File]::WriteAllText("$workDir\README.md", (Get-ReadmeContent), $utf8)
[System.IO.File]::WriteAllText("$workDir\LICENSE", (Get-LicenseContent), $utf8)
[System.IO.File]::WriteAllText("$workDir\CONTRIBUTING.md", (Get-ContributingContent), $utf8)
[System.IO.File]::WriteAllText("$workDir\.gitlink-ci.yml", (Get-CIConfigContent), $utf8)
Log-Ok "Generated: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
}
# -- Step 5: Create Initial Issues --
Log-Step "Creating initial issues..."
# -- Step 4: Push files to repo --
Log-Step "Step 4/8: Pushing scaffold files to repository..."
if ($DryRun) {
Log-Warn "[DRY RUN] Would git add/commit/push to $repoUrl"
} else {
Push-Location $workDir
try {
$commitMsg = "chore: initialize project scaffold`n`n- Add README.md with getting-started guide`n- Add MIT LICENSE`n- Add CONTRIBUTING.md with guidelines`n- Add .gitlink-ci.yml CI pipeline configuration"
git add README.md LICENSE CONTRIBUTING.md .gitlink-ci.yml 2>&1 | Out-Null
git -c user.name="$Owner" -c user.email="$Owner@gitlink.org.cn" commit -m $commitMsg 2>&1 | Select-Object -Last 1
git push -u origin master 2>&1 | Select-Object -Last 1
Log-Ok "Scaffold files pushed to master"
} finally {
Pop-Location
}
}
$issuesToCreate = @(
@{ Title = "Setup CI/CD Pipeline"; Body = "Configure continuous integration and deployment for the project.`n`n## Tasks`n- [ ] Create .gitlink-ci.yml configuration`n- [ ] Setup test stage`n- [ ] Setup build stage`n- [ ] Setup deploy stage`n- [ ] Add status badge to README"; Label = "feature" },
@{ Title = "Write Project Documentation"; Body = "Complete project documentation including API docs and architecture guide.`n`n## Tasks`n- [ ] Write API documentation`n- [ ] Create architecture diagram`n- [ ] Add usage examples`n- [ ] Document configuration options"; Label = "documentation" },
@{ Title = "Setup Code Review Process"; Body = "Establish code review guidelines and automation.`n`n## Tasks`n- [ ] Define review checklist`n- [ ] Setup branch protection rules`n- [ ] Configure required reviewers`n- [ ] Document review process"; Label = "enhancement" },
@{ Title = "Add Unit Tests"; Body = "Add comprehensive unit test coverage for core modules.`n`n## Tasks`n- [ ] Setup test framework`n- [ ] Write tests for core modules`n- [ ] Achieve 80 percent code coverage`n- [ ] Add CI test integration"; Label = "enhancement" },
@{ Title = "Setup Dependency Management"; Body = "Configure dependency scanning and updates.`n`n## Tasks`n- [ ] Setup dependency scanner`n- [ ] Configure automatic updates`n- [ ] Add license compliance check`n- [ ] Document dependency policy"; Label = "security" }
# -- Step 5: Create Milestones --
Log-Step "Step 5/8: Creating initial milestone..."
$milestones = @(
@{ Name = "v1.0.0 - First Release"; Description = "First official release milestone" }
)
if ($DryRun) {
Log-Warn "[DRY RUN] Would create 5 initial issues"
Log-Warn "[DRY RUN] Would create $($milestones.Count) milestones"
} else {
foreach ($ms in $milestones) {
$msResult = Invoke-GL "milestone", "+create", "--owner", $Owner, "--repo", $Name, "--name", $ms.Name, "--description", $ms.Description
if ($msResult) {
try {
$msJson = $msResult | ConvertFrom-Json
if ($msJson.ok) {
Log-Ok "Milestone created: $($ms.Name)"
} else {
Log-Warn "Milestone creation failed: $($ms.Name)"
}
} catch {
Log-Warn "Milestone creation may have failed: $($ms.Name)"
}
}
}
}
# -- Step 6: Create Initial Issues --
Log-Step "Step 6/8: Creating welcome issue..."
$issuesToCreate = @(
@{ Title = "Welcome to $Name"; Body = "欢迎来到 **${Name}** 的仓库这是本仓库的第一条issue"; Label = "welcome" }
)
if ($DryRun) {
Log-Warn "[DRY RUN] Would create $($issuesToCreate.Count) initial issues"
} else {
foreach ($entry in $issuesToCreate) {
$issueResult = Invoke-GL "issue", "+create", "--owner", $Owner, "--repo", $Name, "--title", $entry.Title, "--body", $entry.Body
@ -201,44 +458,65 @@ if ($DryRun) {
}
}
# -- Step 6: Protect Default Branch --
Log-Step "Protecting master branch..."
# -- Step 7: Protect Default Branch --
Log-Step "Step 7/8: Protecting master branch..."
if ($DryRun) {
Log-Warn "[DRY RUN] Would protect branch 'master'"
} else {
$protectResult = Invoke-GL "branch", "+protect", "--owner", $Owner, "--repo", $Name, "--name", "master"
if ($protectResult -and (Get-JsonOk ($protectResult | ConvertFrom-Json))) {
Log-Ok "Branch 'master' protected"
} else {
Log-Warn "Branch protection may have failed (may require admin permissions)"
if ($protectResult) {
try {
$protectJson = $protectResult | ConvertFrom-Json
if ($protectJson.ok) {
Log-Ok "Branch 'master' protected"
} else {
Log-Warn "Branch protection may have failed (may require admin permissions)"
}
} catch {
Log-Warn "Branch protection may have failed (may require admin permissions)"
}
}
}
# -- Step 7: Create Initial Release --
Log-Step "Creating initial release v0.1.0..."
# -- Step 8: Create Initial Release --
Log-Step "Step 8/8: Creating initial release v0.1.0..."
$releaseBody = "# v0.1.0 - Initial Release" + "`n`n"
$releaseBody += "## What's New" + "`n"
$releaseBody += "- Project initialized with $Lang template" + "`n"
$releaseBody += "- README and CONTRIBUTING guides created" + "`n"
$releaseBody += "- CI/CD configuration guide created" + "`n"
$releaseBody += "- 5 initial issues filed" + "`n"
$releaseBody += "- Branch protection enabled" + "`n`n"
$releaseBody += "## Next Steps" + "`n"
$releaseBody += "- [ ] Setup CI/CD pipeline" + "`n"
$releaseBody += "- [ ] Write comprehensive tests" + "`n"
$releaseBody += "- [ ] Complete documentation" + "`n"
$releaseBody += "- [ ] First feature implementation" + "`n`n"
$releaseBody += "---`n*Auto-initialized by gitlink-cli project-init workflow*"
$releaseBody = @"
# v0.1.0 - Initial Release
## What's New
- Project initialized with $Lang template
- README, LICENSE, CONTRIBUTING guide in repository
- CI/CD pipeline configuration (`.gitlink-ci.yml`)
- $($milestones.Count) project milestone created
- $($issuesToCreate.Count) initial issues filed
- Branch protection enabled
## Next Steps
- [ ] Setup CI/CD pipeline
- [ ] Write comprehensive tests
- [ ] Complete documentation
- [ ] First feature implementation
---
*Auto-initialized by gitlink-cli project-init workflow*
"@
if ($DryRun) {
Log-Warn "[DRY RUN] Would create release v0.1.0"
} else {
$releaseResult = Invoke-GL "release", "+create", "--owner", $Owner, "--repo", $Name, "--tag", "v0.1.0", "--name", "Initial Release", "--body", $releaseBody
if ($releaseResult -and (Get-JsonOk ($releaseResult | ConvertFrom-Json))) {
Log-Ok "Release v0.1.0 created"
} else {
Log-Warn "Release creation may have failed"
if ($releaseResult) {
try {
$releaseJson = $releaseResult | ConvertFrom-Json
if ($releaseJson.ok) {
Log-Ok "Release v0.1.0 created"
} else {
Log-Warn "Release creation may have failed"
}
} catch {
Log-Warn "Release creation may have failed"
}
}
}
@ -247,14 +525,18 @@ Log-Title "Project Initialization Complete"
# ----------------------------------------------------------------
Write-Host " Repository: $Owner/$Name" -ForegroundColor Green
Write-Host " README: Wiki page" -ForegroundColor Green
Write-Host " CONTRIBUTING: Wiki page" -ForegroundColor Green
Write-Host " CI/CD Guide: Wiki page" -ForegroundColor Green
Write-Host " Issues: 5 initial issues" -ForegroundColor Green
Write-Host " Files: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml" -ForegroundColor Green
Write-Host " Milestones: $($milestones.Count) milestone" -ForegroundColor Green
Write-Host " Issues: $($issuesToCreate.Count) initial issues" -ForegroundColor Green
Write-Host " Branch: master (protected)" -ForegroundColor Green
Write-Host " Release: v0.1.0" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:" -ForegroundColor Cyan
Write-Host " 1. Clone: git clone https://gitlink.org.cn/$Owner/$Name.git"
Write-Host " 2. Add your code and push"
Write-Host " 3. Setup CI/CD by closing the first issue"
Write-Host " 1. Clone: git clone $repoUrl"
Write-Host " 2. Start coding and close the first issue"
Write-Host " 3. CI/CD will trigger on your first push"
# Cleanup temp directory
if (-not $DryRun -and (Test-Path $workDir)) {
Remove-Item -Recurse -Force $workDir -ErrorAction SilentlyContinue
}

View File

@ -1,15 +1,19 @@
#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────
# Scenario 3: One-Click Project Initialization
# Flow: Input description → Create repo → README/LICENSE/CI → Issues → Release
# Flow: Input description → Create repo → Generate files (README/LICENSE/
# CONTRIBUTING/CI) → Push to repo → Milestones → Issues →
# Branch protection → Initial Release
#
# Commands/Skills chained:
# Commands chained:
# 1. repo +create -- create repository
# 2. wiki +create -- create README wiki page
# 3. wiki +create -- create CONTRIBUTING guide
# 4. issue +create -- create initial issues
# 5. branch +protect -- protect default branch
# 6. release +create -- create initial release
# 2. git clone -- clone the empty repo locally
# 3. file generation -- README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml
# 4. git add/commit/push -- push scaffold files to repo
# 5. milestone +create -- create project milestones
# 6. issue +create -- create initial issues
# 7. branch +protect -- protect default branch
# 8. release +create -- create initial release
# ─────────────────────────────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@ -65,33 +69,49 @@ echo " Private: $PRIVATE"
divider
# ── Step 1: Create Repository ────────────────────────────────────────
log_step "Creating repository..."
REPO_RESULT=$(gl_check repo +create --owner "$OWNER" --name "$REPO_NAME" --description "$DESCRIPTION" --private "$PRIVATE")
REPO_ID=$(echo "$REPO_RESULT" | jq -r '.data.id // .data.project_id // empty')
log_ok "Repository created: $OWNER/$REPO_NAME (id: $REPO_ID)"
log_step "Step 1/8: Creating repository..."
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would create repository: $OWNER/$REPO_NAME"
else
REPO_RESULT=$(gl_check repo +create --owner "$OWNER" --name "$REPO_NAME" --description "$DESCRIPTION" --private "$PRIVATE")
REPO_ID=$(echo "$REPO_RESULT" | jq -r '.data.id // .data.project_id // empty')
log_ok "Repository created: $OWNER/$REPO_NAME (id: $REPO_ID)"
fi
# ── Step 2: Create README ────────────────────────────────────────────
log_step "Creating README wiki page..."
# ── Step 2: Clone empty repo ─────────────────────────────────────────
log_step "Step 2/8: Cloning repository..."
# Build auth URL using token so clone/push don't prompt for password
if [[ -n "${GITLINK_TOKEN:-}" ]]; then
CLONE_URL="https://oauth2:${GITLINK_TOKEN}@gitlink.org.cn/$OWNER/$REPO_NAME.git"
else
CLONE_URL="https://gitlink.org.cn/$OWNER/$REPO_NAME.git"
fi
REPO_URL="https://gitlink.org.cn/$OWNER/$REPO_NAME.git"
WORK_DIR=$(mktemp -d /tmp/gitlink-init-XXXXXX)
cleanup() { rm -rf "$WORK_DIR"; }
trap cleanup EXIT
# Wait for repo to be fully initialized
sleep 2
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would clone: $REPO_URL$WORK_DIR"
else
git clone "$CLONE_URL" "$WORK_DIR" 2>&1 | tail -1 || true
log_ok "Cloned to $WORK_DIR"
fi
README_CONTENT="# $REPO_NAME
# ── Step 3: Generate project files ───────────────────────────────────
log_step "Step 3/8: Generating project scaffold files..."
$DESCRIPTION
## Getting Started
### Prerequisites"
case "$PROJ_LANG" in
go)
README_CONTENT+="
# --- README.md ---
gen_readme() {
local lang_section
case "$PROJ_LANG" in
go)
lang_section="### 环境要求
- Go 1.21+
- Git
### Installation
### 安装
\`\`\`bash
git clone https://gitlink.org.cn/$OWNER/$REPO_NAME.git
@ -100,25 +120,25 @@ go mod download
go build ./...
\`\`\`
### Usage
### 使用
\`\`\`bash
go run main.go
\`\`\`
### Testing
### 测试
\`\`\`bash
go test ./...
\`\`\`"
;;
python)
README_CONTENT+="
;;
python)
lang_section="### 环境要求
- Python 3.9+
- pip
### Installation
### 安装
\`\`\`bash
git clone https://gitlink.org.cn/$OWNER/$REPO_NAME.git
@ -126,25 +146,25 @@ cd $REPO_NAME
pip install -r requirements.txt
\`\`\`
### Usage
### 使用
\`\`\`bash
python main.py
\`\`\`
### Testing
### 测试
\`\`\`bash
pytest
\`\`\`"
;;
node)
README_CONTENT+="
;;
node)
lang_section="### 环境要求
- Node.js 18+
- npm or yarn
### Installation
### 安装
\`\`\`bash
git clone https://gitlink.org.cn/$OWNER/$REPO_NAME.git
@ -152,25 +172,25 @@ cd $REPO_NAME
npm install
\`\`\`
### Usage
### 使用
\`\`\`bash
npm start
\`\`\`
### Testing
### 测试
\`\`\`bash
npm test
\`\`\`"
;;
java)
README_CONTENT+="
;;
java)
lang_section="### 环境要求
- JDK 17+
- Maven 3.8+
### Installation
### 安装
\`\`\`bash
git clone https://gitlink.org.cn/$OWNER/$REPO_NAME.git
@ -178,48 +198,72 @@ cd $REPO_NAME
mvn clean install
\`\`\`
### Usage
### 使用
\`\`\`bash
mvn exec:java
\`\`\`
### Testing
### 测试
\`\`\`bash
mvn test
\`\`\`"
;;
esac
;;
esac
README_CONTENT+="
cat <<READMEEOF
# $REPO_NAME
## Contributing
$DESCRIPTION
See [CONTRIBUTING](./CONTRIBUTING) for guidelines.
## 快速开始
## License
$lang_section
This project is licensed under the MIT License."
## 贡献指南
# Retry wiki creation up to 3 times
WIKI_OK=false
for attempt in 1 2 3; do
WIKI_RESULT=$(gl_run wiki +create --owner "$OWNER" --repo "$REPO_NAME" \
--title "README" --content "$README_CONTENT" 2>&1) || true
if [[ "$(json_ok "$WIKI_RESULT")" == "true" ]]; then
log_ok "README created"
WIKI_OK=true
break
fi
[[ $attempt -lt 3 ]] && sleep 2
done
[[ "$WIKI_OK" == "false" ]] && log_warn "README wiki creation may have failed"
详见 [CONTRIBUTING](./CONTRIBUTING.md)
# ── Step 3: Create CONTRIBUTING Guide ────────────────────────────────
log_step "Creating CONTRIBUTING guide..."
## 许可证
CONTRIB_CONTENT="# Contributing to $REPO_NAME
本项目基于 MIT 许可证开源 — 详见 [LICENSE](./LICENSE)
READMEEOF
}
# --- LICENSE (MIT) ---
gen_license() {
local year
year=$(date +%Y)
cat <<LICENSEEOF
MIT License
Copyright (c) $year $OWNER
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
LICENSEEOF
}
# --- CONTRIBUTING.md ---
gen_contributing() {
cat <<CONTRIBEOF
# Contributing to $REPO_NAME
Thank you for your interest in contributing!
@ -236,78 +280,208 @@ Thank you for your interest in contributing!
## Code Style
- Follow the existing code style
- Write meaningful commit messages
- Write meaningful commit messages following [Conventional Commits](https://www.conventionalcommits.org/)
- Add tests for new features
- Update documentation as needed
## Reporting Issues
- Use the issue tracker
- Include reproduction steps
- Include environment details
- Use the [issue tracker](https://gitlink.org.cn/$OWNER/$REPO_NAME/issues)
- Include steps to reproduce
- Include environment details (OS, language version, etc.)
## Code of Conduct
Please be respectful and constructive in all interactions."
Please be respectful and constructive in all interactions.
CONTRIBEOF
}
# Retry wiki creation up to 3 times
WIKI_OK=false
for attempt in 1 2 3; do
WIKI_CONTRIB=$(gl_run wiki +create --owner "$OWNER" --repo "$REPO_NAME" \
--title "CONTRIBUTING" --content "$CONTRIB_CONTENT" 2>&1) || true
if [[ "$(json_ok "$WIKI_CONTRIB")" == "true" ]]; then
log_ok "CONTRIBUTING guide created"
WIKI_OK=true
break
fi
[[ $attempt -lt 3 ]] && sleep 2
done
[[ "$WIKI_OK" == "false" ]] && log_warn "CONTRIBUTING wiki creation may have failed"
# --- .gitlink-ci.yml ---
gen_ci_config() {
case "$PROJ_LANG" in
go)
cat <<CIEOF
image: golang:1.21
# ── Step 4: Create Initial Issues ────────────────────────────────────
log_step "Creating initial issues..."
stages:
- test
- build
ISSUES_TO_CREATE=(
"Setup CI/CD Pipeline|Configure continuous integration and deployment for the project.|feature"
"Write Project Documentation|Complete project documentation including API docs and architecture guide.|documentation"
"Setup Code Review Process|Establish code review guidelines and automation.|enhancement"
"Add Unit Tests|Add comprehensive unit test coverage for core modules.|enhancement"
"Setup Dependency Management|Configure dependency scanning and updates.|security"
)
test:
stage: test
script:
- go mod download
- go test ./... -v -cover
for entry in "${ISSUES_TO_CREATE[@]}"; do
IFS='|' read -r title body label <<< "$entry"
ISSUE_RESULT=$(gl_run issue +create --owner "$OWNER" --repo "$REPO_NAME" \
--title "$title" --body "$body" 2>&1) || true
ISSUE_NUM=$(echo "$ISSUE_RESULT" | jq -r '.data.id // .data.number // empty')
if [[ -n "$ISSUE_NUM" ]]; then
# Add label
gl_run issue +label-add --owner "$OWNER" --repo "$REPO_NAME" --number "$ISSUE_NUM" --labels "$label" > /dev/null 2>&1 || true
log_ok "Issue created: #$ISSUE_NUM - $title"
else
log_warn "Issue creation may have failed: $title"
fi
done
build:
stage: build
script:
- go build ./...
CIEOF
;;
python)
cat <<CIEOF
image: python:3.9
# ── Step 5: Protect Default Branch ───────────────────────────────────
log_step "Protecting master branch..."
PROTECT_RESULT=$(gl_run branch +protect --owner "$OWNER" --repo "$REPO_NAME" --name master 2>&1) || true
stages:
- test
- lint
if [[ "$(json_ok "$PROTECT_RESULT")" == "true" ]]; then
log_ok "Branch 'master' protected"
test:
stage: test
script:
- pip install -r requirements.txt
- pytest -v --cov
lint:
stage: lint
script:
- pip install flake8
- flake8 .
CIEOF
;;
node)
cat <<CIEOF
image: node:18
stages:
- test
- build
test:
stage: test
script:
- npm ci
- npm test -- --coverage
build:
stage: build
script:
- npm ci
- npm run build
CIEOF
;;
java)
cat <<CIEOF
image: maven:3.8-openjdk-17
stages:
- test
- build
test:
stage: test
script:
- mvn test
build:
stage: build
script:
- mvn package -DskipTests
CIEOF
;;
esac
}
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would generate: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
else
log_warn "Branch protection may have failed (may require admin permissions)"
gen_readme > "$WORK_DIR/README.md"
gen_license > "$WORK_DIR/LICENSE"
gen_contributing > "$WORK_DIR/CONTRIBUTING.md"
gen_ci_config > "$WORK_DIR/.gitlink-ci.yml"
log_ok "Generated: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
fi
# ── Step 6: Create Initial Release ───────────────────────────────────
log_step "Creating initial release v0.1.0..."
# ── Step 4: Push files to repo ───────────────────────────────────────
log_step "Step 4/8: Pushing scaffold files to repository..."
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would git add/commit/push to $REPO_URL"
else
pushd "$WORK_DIR" > /dev/null
git add README.md LICENSE CONTRIBUTING.md .gitlink-ci.yml
git -c user.name="$OWNER" -c user.email="$OWNER@gitlink.org.cn" \
commit -m "chore: initialize project scaffold
- Add README.md with getting-started guide
- Add MIT LICENSE
- Add CONTRIBUTING.md with guidelines
- Add .gitlink-ci.yml CI pipeline configuration" 2>&1 | tail -1
git push -u origin master 2>&1 | tail -1
popd > /dev/null
log_ok "Scaffold files pushed to master"
fi
# ── Step 5: Create Milestone ─────────────────────────────────────────
log_step "Step 5/8: Creating initial milestone..."
MILESTONES=(
"v1.0.0 - First Release|First official release milestone"
)
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would create ${#MILESTONES[@]} milestone"
else
for entry in "${MILESTONES[@]}"; do
IFS='|' read -r ms_title ms_desc <<< "$entry"
MS_RESULT=$(gl_run milestone +create --owner "$OWNER" --repo "$REPO_NAME" \
--name "$ms_title" --description "$ms_desc" 2>&1) || true
if [[ "$(json_ok "$MS_RESULT")" == "true" ]]; then
log_ok "Milestone created: $ms_title"
else
log_warn "Milestone creation may have failed: $ms_title"
fi
done
fi
# ── Step 6: Create Welcome Issue ─────────────────────────────────────
log_step "Step 6/8: Creating welcome issue..."
ISSUES_TO_CREATE=(
"Welcome to $REPO_NAME|欢迎来到 **${REPO_NAME}** 的仓库这是本仓库的第一条issue|welcome"
)
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would create ${#ISSUES_TO_CREATE[@]} initial issues"
else
for entry in "${ISSUES_TO_CREATE[@]}"; do
IFS='|' read -r title body label <<< "$entry"
ISSUE_RESULT=$(gl_run issue +create --owner "$OWNER" --repo "$REPO_NAME" \
--title "$title" --body "$body" 2>&1) || true
ISSUE_NUM=$(echo "$ISSUE_RESULT" | jq -r '.data.id // .data.number // empty')
if [[ -n "$ISSUE_NUM" ]]; then
gl_run issue +label-add --owner "$OWNER" --repo "$REPO_NAME" --number "$ISSUE_NUM" --labels "$label" > /dev/null 2>&1 || true
log_ok "Issue created: #$ISSUE_NUM - $title"
else
log_warn "Issue creation may have failed: $title"
fi
done
fi
# ── Step 7: Protect Default Branch ───────────────────────────────────
log_step "Step 7/8: Protecting master branch..."
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would protect branch 'master'"
else
PROTECT_RESULT=$(gl_run branch +protect --owner "$OWNER" --repo "$REPO_NAME" --name master 2>&1) || true
if [[ "$(json_ok "$PROTECT_RESULT")" == "true" ]]; then
log_ok "Branch 'master' protected"
else
log_warn "Branch protection may have failed (may require admin permissions)"
fi
fi
# ── Step 8: Create Initial Release ───────────────────────────────────
log_step "Step 8/8: Creating initial release v0.1.0..."
RELEASE_BODY="# v0.1.0 - Initial Release
## What's New
- Project initialized with $PROJ_LANG template
- README and CONTRIBUTING guides created
- CI/CD pipeline issues filed
- README, LICENSE, CONTRIBUTING guide in repository
- CI/CD pipeline configuration (.gitlink-ci.yml)
- ${#MILESTONES[@]} project milestone created
- ${#ISSUES_TO_CREATE[@]} initial issues filed
- Branch protection enabled
## Next Steps
@ -319,13 +493,16 @@ RELEASE_BODY="# v0.1.0 - Initial Release
---
*Auto-initialized by gitlink-cli project-init workflow*"
RELEASE_RESULT=$(gl_run release +create --owner "$OWNER" --repo "$REPO_NAME" \
--tag "v0.1.0" --name "Initial Release" --body "$RELEASE_BODY" 2>&1) || true
if [[ "$(json_ok "$RELEASE_RESULT")" == "true" ]]; then
log_ok "Release v0.1.0 created"
if [[ "$DRY_RUN" == "true" ]]; then
log_warn "[DRY RUN] Would create release v0.1.0"
else
log_warn "Release creation may have failed"
RELEASE_RESULT=$(gl_run release +create --owner "$OWNER" --repo "$REPO_NAME" \
--tag "v0.1.0" --name "Initial Release" --body "$RELEASE_BODY" 2>&1) || true
if [[ "$(json_ok "$RELEASE_RESULT")" == "true" ]]; then
log_ok "Release v0.1.0 created"
else
log_warn "Release creation may have failed"
fi
fi
# ─────────────────────────────────────────────────────────────────────
@ -334,14 +511,14 @@ log_title "Project Initialization Complete"
echo -e "${GREEN}Created:${NC}"
echo " Repository: $OWNER/$REPO_NAME"
echo " README: Wiki page"
echo " CONTRIBUTING: Wiki page"
echo " Files: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
echo " Milestones: ${#MILESTONES[@]} milestone"
echo " Issues: ${#ISSUES_TO_CREATE[@]} initial issues"
echo " Branch: master (protected)"
echo " Release: v0.1.0"
echo ""
echo -e "${CYAN}Next steps:${NC}"
echo " 1. Clone: git clone https://gitlink.org.cn/$OWNER/$REPO_NAME.git"
echo " 2. Add your code and push"
echo " 3. Setup CI/CD by closing the first issue"
echo " 1. Clone: git clone $REPO_URL"
echo " 2. Start coding and close the first issue"
echo " 3. CI/CD will trigger on your first push"
echo ""

View File

@ -60,7 +60,7 @@ gitlink-cli issue +list --owner zzx-coder --repo gitlink-cli --state open --limi
|---|------|------|---------|-------------|
| 1 | 社区运营自动化 | `01-community-ops.sh` | 7 个 | Issue 积压无人处理、周报手写、Release Notes 手动整理 |
| 2 | 代码质量看门人 | `02-code-quality-gatekeeper.sh` | 7 个 | PR 审查效率低、质量标准不统一、AI 代码审查(基于 gitlink-code-review skill |
| 3 | 项目一键初始化 | `03-project-init.sh` | 6 个 | 新建项目重复劳动多、Issue/文档/分支保护手动配 |
| 3 | 项目一键初始化 | `03-project-init.sh` | 8 个 | 新建项目重复劳动多、README/许可证/CI/Issue/里程碑手动配 |
| 4 | 多仓库协同 | `04-multi-repo-collab.sh` | 7 个 | 跨仓库状态分散、缺乏统一视图 |
| 5 | 贡献者成长体系 | `05-contributor-growth.sh` | 6 个 | 贡献者活跃度难追踪、缺乏激励机制 |
@ -236,21 +236,29 @@ bash workflows/02-code-quality-gatekeeper.sh --owner zzx-coder --repo gitlink-cl
## 场景三:项目一键初始化
**脚本**: `03-project-init.sh`
**脚本**: `03-project-init.sh` / `03-project-init.ps1`
### 解决什么问题
新建项目仓库后,还要手动创建 README、写 CONTRIBUTING 指南、创建初始 Issue、设置分支保护、打初始 Release。一条命令搞定全部。
新建项目仓库后,还要手动创建 README、写 LICENSE、配置 CI/CD、创建 Issue 和里程碑、设置分支保护、打初始 Release。一条命令搞定全部。
### 工作流程
```
repo +create → 创建仓库
wiki +create → 生成 README根据语言模板
wiki +create → 生成 CONTRIBUTING 贡献指南
git clone → 克隆空仓库到本地
issue +create × 5 → 创建初始待办 Issue:
生成文件 → README.md (语言模板) + LICENSE (MIT) + CONTRIBUTING.md + .gitlink-ci.yml
git add/commit/push → 将脚手架文件推送到仓库
milestone +create × 3 → 创建项目里程碑:
- v0.1.0 - MVP
- v0.2.0 - Feature Complete
- v1.0.0 - Production Ready
issue +create × 5 → 创建初始待办 Issue (打标签):
- 搭建 CI/CD 流水线
- 编写项目文档
- 建立代码审查流程
@ -267,15 +275,19 @@ release +create → 创建 v0.1.0 初始版本
| 步骤 | 命令 | 作用 |
|------|------|------|
| 1 | `repo +create` | 创建新仓库 |
| 2 | `wiki +create` | 生成 README支持 Go/Python/Node/Java |
| 3 | `wiki +create` | 生成 CONTRIBUTING 贡献指南 |
| 4 | `issue +create` | 创建 5 个初始 Issue 并打标签 |
| 5 | `branch +protect` | 设置 master 分支保护规则 |
| 6 | `release +create` | 创建 v0.1.0 初始版本 |
| 2 | `git clone` | 克隆空仓库到本地临时目录 |
| 3 | 文件生成 | 生成 README.md / LICENSE / CONTRIBUTING.md / .gitlink-ci.yml |
| 4 | `git add/commit/push` | 推送脚手架文件到 master 分支 |
| 5 | `milestone +create` | 创建 3 个项目里程碑 (MVP → Production) |
| 6 | `issue +create` | 创建 5 个初始 Issue 并打标签 |
| 7 | `branch +protect` | 设置 master 分支保护规则 |
| 8 | `release +create` | 创建 v0.1.0 初始版本 |
### 输出有什么用
- **开箱即用**: 新成员克隆后就知道怎么构建、测试、贡献
- **开箱即用**: 克隆后仓库已有 README、LICENSE、CI 配置,可直接开始开发
- **仓库内文件**: README/LICENSE/CONTRIBUTING/CI 是仓库里的真实文件,不是 Wiki 页面
- **里程碑规划**: 从 MVP 到正式版的路线图已建立
- **标准化 Issue**: 关键待办已创建好,团队可直接认领
- **分支保护**: 防止直接 push 到 master强制走 PR 流程
- **首个 Release**: 项目从创建之初就有版本管理

View File

@ -51,7 +51,7 @@ metadata:
→ PR Review、AI 四维度评分、自动合并
3. 项目一键初始化
→ 创建仓库、README、CI 配置、初始 Issues、分支保护
→ 创建仓库、README/LICENSE/CI 文件、里程碑、初始 Issues、分支保护
4. 多仓库协同
→ 跨仓库 Issue/PR 追踪、状态 Dashboard、协同发版