gitlink-cli/workflows/03-project-init.ps1

543 lines
14 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ----------------------------------------------------------------
# Scenario 3: One-Click Project Initialization
# 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. 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
param(
[string]$Owner = "",
[string]$Name = "",
[string]$Description = "",
[string]$Lang = "go",
[switch]$Private,
[switch]$DryRun,
[switch]$Help
)
$ErrorActionPreference = "Stop"
Import-Module "$PSScriptRoot/lib/common.psm1" -Force -WarningAction SilentlyContinue
if ($Help) {
Write-Host "Usage: powershell 03-project-init.ps1 -Owner OWNER -Name REPO_NAME -Description DESC [-Lang go|python|node|java] [-Private] [-DryRun]"
exit 0
}
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
if (-not $Owner) {
$detected = Detect-OwnerRepo
$Owner = $detected.Owner
}
# ----------------------------------------------------------------
Log-Title "Project Initialization: $Owner/$Name"
# ----------------------------------------------------------------
Write-Host " Owner: $Owner"
Write-Host " Name: $Name"
Write-Host " Description: $Description"
Write-Host " Language: $Lang"
Write-Host " Private: $($Private.IsPresent)"
Divider
# -- Step 1: Create Repository --
Log-Step "Step 1/8: Creating repository..."
if ($DryRun) {
Log-Warn "[DRY RUN] Would create repository: $Owner/$Name"
} else {
$privateStr = if ($Private) { "true" } else { "false" }
$repoResult = Invoke-GLCheck "repo", "+create", "--owner", $Owner, "--name", $Name, "--description", $Description, "--private", $privateStr
if ($repoResult) {
Log-Ok "Repository created: $Owner/$Name"
} else {
Log-Err "Repository creation failed"
exit 1
}
}
# -- 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
}
$workDir = Join-Path $env:TEMP "gitlink-init-$([System.Guid]::NewGuid().ToString('N').Substring(0, 8))"
if ($DryRun) {
Log-Warn "[DRY RUN] Would clone: $repoUrl -> $workDir"
} else {
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 ./...
```
"@
}
"python" {
@"
###
- Python 3.9+
- pip
###
```bash
git clone https://gitlink.org.cn/$Owner/$Name.git
cd $Name
pip install -r requirements.txt
```
### 使
```bash
python main.py
```
###
```bash
pytest
```
"@
}
"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 { "" }
}
return @"
# $Name
$Description
##
$langSection
##
[CONTRIBUTING](./CONTRIBUTING.md)
##
MIT [LICENSE](./LICENSE)
"@
}
function Get-LicenseContent {
$year = (Get-Date).Year
return @"
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.
"@
}
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 generate: README.md, LICENSE, CONTRIBUTING.md, .gitlink-ci.yml"
} else {
$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 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
}
}
# -- 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 $($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
if ($issueResult) {
try {
$issueJson = $issueResult | ConvertFrom-Json
$issueNum = if ($issueJson.ok -and $issueJson.data.id) { $issueJson.data.id } elseif ($issueJson.ok -and $issueJson.data.number) { $issueJson.data.number } else { $null }
if ($issueNum) {
Invoke-GL "issue", "+label-add", "--owner", $Owner, "--repo", $Name, "--number", $issueNum, "--labels", $entry.Label | Out-Null
Log-Ok "Issue created: #$issueNum - $($entry.Title)"
}
} catch {
Log-Warn "Issue creation may have failed: $($entry.Title)"
}
}
}
}
# -- 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) {
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 8: Create Initial Release --
Log-Step "Step 8/8: Creating initial release v0.1.0..."
$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) {
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"
}
}
}
# ----------------------------------------------------------------
Log-Title "Project Initialization Complete"
# ----------------------------------------------------------------
Write-Host " Repository: $Owner/$Name" -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 $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
}