Skip to content

Commit 1de8dc9

Browse files
authored
Merge pull request #90 from cbullinger/batch
feat(copier): add support for batching files in single PR and to use PR template
2 parents 21161b4 + 0c54b83 commit 1de8dc9

37 files changed

+3453
-453
lines changed

examples-copier/.dockerignore

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Git
2+
.git
3+
.gitignore
4+
.github
5+
6+
# Documentation
7+
*.md
8+
!README.md
9+
docs/
10+
readme_files/
11+
12+
# Test files
13+
*_test.go
14+
test-payloads/
15+
tests/
16+
17+
# Config examples (not needed in container)
18+
configs/*.example
19+
configs/*.production
20+
configs/README.md
21+
configs/.env*
22+
23+
# Scripts (not needed in container)
24+
scripts/
25+
26+
# Build artifacts
27+
*.log
28+
all.log
29+
30+
# Environment files (will be set via Cloud Run env vars)
31+
.env
32+
.env.*
33+
env.yaml
34+
env-cloudrun.yaml
35+
app.yaml
36+
37+
# IDE
38+
.vscode
39+
.idea
40+
*.swp
41+
*.swo
42+
*~
43+
44+
# OS
45+
.DS_Store
46+
Thumbs.db
47+
48+
# Temporary files
49+
tmp/
50+
temp/
51+

examples-copier/.gitignore

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Binaries
22
examples-copier
33
code-copier
4+
copier
45
*.exe
56
*.exe~
67
*.dll
@@ -19,13 +20,23 @@ vendor/
1920
# Go workspace file
2021
go.work
2122

22-
# Environment files with secrets
23+
# Environment files with secrets (working files - create from templates in configs/)
24+
# Working files (create from templates):
25+
# env.yaml - App Engine deployment config (from configs/env.yaml.*)
26+
# env-cloudrun.yaml - Cloud Run deployment config (from configs/env.yaml.*)
27+
# .env - Local development config (from configs/.env.local.example)
2328
env.yaml
29+
env-cloudrun.yaml
2430
.env
2531
.env.local
2632
.env.production
2733
.env.*.local
2834

35+
# Explicitly keep template files in configs/ directory (these should be tracked)
36+
!configs/env.yaml.example
37+
!configs/env.yaml.production
38+
!configs/.env.local.example
39+
2940
# Private keys
3041
*.pem
3142
*.key
@@ -47,5 +58,3 @@ Thumbs.db
4758
# Temporary files
4859
tmp/
4960
temp/
50-
51-
env.yaml

examples-copier/Dockerfile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Build stage
2+
FROM golang:1.23.4-alpine AS builder
3+
4+
# Install build dependencies
5+
RUN apk add --no-cache git ca-certificates
6+
7+
WORKDIR /app
8+
9+
# Copy go mod files first for better caching
10+
COPY go.mod go.sum ./
11+
RUN go mod download
12+
13+
# Copy source code
14+
COPY . .
15+
16+
# Build the binary
17+
# CGO_ENABLED=0 for static binary (no C dependencies)
18+
# -ldflags="-w -s" strips debug info to reduce size
19+
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o examples-copier .
20+
21+
# Runtime stage
22+
FROM alpine:latest
23+
24+
# Install ca-certificates for HTTPS requests
25+
RUN apk --no-cache add ca-certificates
26+
27+
WORKDIR /root/
28+
29+
# Copy binary from builder
30+
COPY --from=builder /app/examples-copier .
31+
32+
# Cloud Run sets PORT environment variable
33+
# Our app reads it from config.Port (defaults to 8080)
34+
EXPOSE 8080
35+
36+
# Run the binary
37+
CMD ["./examples-copier"]
38+

examples-copier/QUICK-REFERENCE.md

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
./config-validator test-pattern -type regex -pattern "^examples/(?P<lang>[^/]+)/.*$" -file "examples/go/main.go"
3232

3333
# Test transformation
34-
./config-validator test-transform -template "docs/${lang}/${file}" -file "examples/go/main.go" -pattern "^examples/(?P<lang>[^/]+)/(?P<file>.+)$"
34+
./config-validator test-transform -source "examples/go/main.go" -template "docs/${lang}/${file}" -vars "lang=go,file=main.go"
3535

3636
# Initialize new config
3737
./config-validator init -output copier-config.yaml
@@ -63,6 +63,18 @@ source_pattern:
6363
pattern: "^examples/(?P<lang>[^/]+)/(?P<file>.+)$"
6464
```
6565
66+
### Pattern with Exclusions
67+
```yaml
68+
source_pattern:
69+
type: "prefix"
70+
pattern: "examples/"
71+
exclude_patterns:
72+
- "\.gitignore$"
73+
- "node_modules/"
74+
- "\.env$"
75+
- "/dist/"
76+
```
77+
6678
## Path Transformations
6779
6880
### Built-in Variables
@@ -102,9 +114,73 @@ commit_strategy:
102114
commit_message: "Update examples"
103115
pr_title: "Update code examples"
104116
pr_body: "Automated update"
117+
use_pr_template: true # Fetch PR template from target repo
105118
auto_merge: true
106119
```
107120

121+
### Batch PRs by Repository
122+
```yaml
123+
batch_by_repo: true
124+
125+
batch_pr_config:
126+
pr_title: "Update from ${source_repo}"
127+
pr_body: |
128+
🤖 Automated update
129+
Files: ${file_count}
130+
use_pr_template: true
131+
commit_message: "Update from ${source_repo} PR #${pr_number}"
132+
```
133+
134+
## Advanced Features
135+
136+
### Exclude Patterns
137+
Exclude unwanted files from being copied:
138+
139+
```yaml
140+
source_pattern:
141+
type: "prefix"
142+
pattern: "examples/"
143+
exclude_patterns:
144+
- "\.gitignore$" # Exclude .gitignore
145+
- "node_modules/" # Exclude dependencies
146+
- "\.env$" # Exclude .env files
147+
- "\.env\\..*$" # Exclude .env.local, .env.production, etc.
148+
- "/dist/" # Exclude build output
149+
- "/build/" # Exclude build artifacts
150+
- "\.test\.(js|ts)$" # Exclude test files
151+
```
152+
153+
### PR Template Integration
154+
Fetch and merge PR templates from target repos:
155+
156+
```yaml
157+
commit_strategy:
158+
type: "pull_request"
159+
pr_body: |
160+
🤖 Automated update
161+
Files: ${file_count}
162+
use_pr_template: true # Fetches .github/pull_request_template.md
163+
```
164+
165+
**Result:** PR description shows:
166+
1. Target repo's PR template (checklists, guidelines)
167+
2. Separator (`---`)
168+
3. Your configured content (automation info)
169+
170+
### Batch Configuration
171+
When `batch_by_repo: true`, use `batch_pr_config` for accurate file counts:
172+
173+
```yaml
174+
batch_by_repo: true
175+
176+
batch_pr_config:
177+
pr_title: "Update from ${source_repo}"
178+
pr_body: |
179+
Files: ${file_count} # Accurate count across all rules
180+
Source: ${source_repo} PR #${pr_number}
181+
use_pr_template: true
182+
```
183+
108184
## Message Templates
109185

110186
### Available Variables

examples-copier/README.md

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# GitHub Docs Code Example Copier
22

3-
A GitHub app that automatically copies code examples and files from a source repository to one or more target repositories when pull requests are merged. Features advanced pattern matching, path transformations, audit logging, and comprehensive monitoring.
3+
A GitHub app that automatically copies code examples and files from a source repository to one or more target
4+
repositories when pull requests are merged. Features advanced pattern matching, path transformations, audit logging,
5+
and comprehensive monitoring.
46

57
## Features
68

@@ -15,6 +17,9 @@ A GitHub app that automatically copies code examples and files from a source rep
1517
### Enhanced Features
1618
- **YAML Configuration** - Modern YAML config with JSON backward compatibility
1719
- **Message Templating** - Template-ized commit messages and PR titles
20+
- **Batch PR Support** - Combine multiple rules into one PR per target repo
21+
- **PR Template Integration** - Fetch and merge PR templates from target repos
22+
- **File Exclusion** - Exclude patterns to filter out unwanted files (`.gitignore`, `node_modules`, etc.)
1823
- **Audit Logging** - MongoDB-based event tracking for all operations
1924
- **Health & Metrics** - `/health` and `/metrics` endpoints for monitoring
2025
- **Development Tools** - Dry-run mode, CLI validation, enhanced logging
@@ -46,7 +51,7 @@ go build -o examples-copier .
4651
go build -o config-validator ./cmd/config-validator
4752
```
4853

49-
### Configuration
54+
### Local Configuration
5055

5156
1. **Copy environment example file**
5257

@@ -96,12 +101,28 @@ Create `copier-config.yaml` in your source repository:
96101
```yaml
97102
source_repo: "your-org/source-repo"
98103
source_branch: "main"
104+
batch_by_repo: true # Optional: batch all changes into one PR per target repo
105+
106+
# Optional: Customize batched PR metadata
107+
batch_pr_config:
108+
pr_title: "Update code examples from ${source_repo}"
109+
pr_body: |
110+
🤖 Automated update of code examples
111+
112+
**Source:** ${source_repo} PR #${pr_number}
113+
**Files:** ${file_count}
114+
use_pr_template: true # Fetch PR template from target repos
115+
commit_message: "Update examples from ${source_repo} PR #${pr_number}"
99116

100117
copy_rules:
101118
- name: "Copy Go examples"
102119
source_pattern:
103120
type: "regex"
104121
pattern: "^examples/(?P<lang>[^/]+)/(?P<category>[^/]+)/(?P<file>.+)$"
122+
exclude_patterns: # Optional: exclude unwanted files
123+
- "\.gitignore$"
124+
- "node_modules/"
125+
- "\.env$"
105126
targets:
106127
- repo: "your-org/target-repo"
107128
branch: "main"
@@ -110,6 +131,8 @@ copy_rules:
110131
type: "pull_request"
111132
commit_message: "Update ${category} examples from ${lang}"
112133
pr_title: "Update ${category} examples"
134+
pr_body: "Automated update of ${lang} examples"
135+
use_pr_template: true # Merge with target repo's PR template
113136
auto_merge: false
114137
deprecation_check:
115138
enabled: true
@@ -203,9 +226,71 @@ commit_strategy:
203226
commit_message: "Update examples"
204227
pr_title: "Update ${category} examples"
205228
pr_body: "Automated update from ${source_repo}"
229+
use_pr_template: true # Fetch and merge PR template from target repo
206230
auto_merge: true
207231
```
208232

233+
### Advanced Features
234+
235+
#### Batch PRs by Repository
236+
237+
Combine all changes from a single source PR into one PR per target repository:
238+
239+
```yaml
240+
batch_by_repo: true
241+
242+
batch_pr_config:
243+
pr_title: "Update code examples from ${source_repo}"
244+
pr_body: |
245+
🤖 Automated update
246+
247+
Files: ${file_count}
248+
Source: ${source_repo} PR #${pr_number}
249+
use_pr_template: true
250+
commit_message: "Update from ${source_repo} PR #${pr_number}"
251+
```
252+
253+
**Benefits:**
254+
- Single PR per target repo instead of multiple PRs
255+
- Accurate `${file_count}` across all matched rules
256+
- Easier review process for related changes
257+
258+
#### PR Template Integration
259+
260+
Automatically fetch and merge PR templates from target repositories:
261+
262+
```yaml
263+
commit_strategy:
264+
type: "pull_request"
265+
pr_body: |
266+
🤖 Automated update
267+
Files: ${file_count}
268+
use_pr_template: true # Fetches .github/pull_request_template.md
269+
```
270+
271+
**Result:** PR description shows the target repo's template first (with checklists and guidelines), followed by your configured content.
272+
273+
#### File Exclusion Patterns
274+
275+
Exclude unwanted files from being copied:
276+
277+
```yaml
278+
source_pattern:
279+
type: "prefix"
280+
pattern: "examples/"
281+
exclude_patterns:
282+
- "\.gitignore$" # Exclude .gitignore files
283+
- "node_modules/" # Exclude dependencies
284+
- "\.env$" # Exclude environment files
285+
- "/dist/" # Exclude build artifacts
286+
- "\.test\.(js|ts)$" # Exclude test files
287+
```
288+
289+
**Use cases:**
290+
- Filter out configuration files
291+
- Exclude build artifacts and dependencies
292+
- Skip test files or documentation
293+
209294
### Message Templates
210295

211296
Use variables in commit messages and PR titles:
@@ -432,7 +517,7 @@ container := NewServiceContainer(config)
432517

433518
## Deployment
434519

435-
See [DEPLOYMENT.md](./docs/DEPLOYMENT.md) for complete deployment guide and [DEPLOYMENT-CHECKLIST.md](./docs/DEPLOYMENT-CHECKLIST.md) for step-by-step checklist.
520+
See [DEPLOYMENT.md](./docs/DEPLOYMENT.md) for complete deployment guide for step-by-step checklist.
436521

437522
### Google Cloud App Engine
438523

examples-copier/cmd/test-webhook/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func main() {
8686
}
8787

8888
func printHelp() {
89-
fmt.Println(`Test Webhook Tool
89+
fmt.Print(`Test Webhook Tool
9090
9191
Usage:
9292
test-webhook [options]

0 commit comments

Comments
 (0)