Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions examples-copier/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Git
.git
.gitignore
.github

# Documentation
*.md
!README.md
docs/
readme_files/

# Test files
*_test.go
test-payloads/
tests/

# Config examples (not needed in container)
configs/*.example
configs/*.production
configs/README.md
configs/.env*

# Scripts (not needed in container)
scripts/

# Build artifacts
*.log
all.log

# Environment files (will be set via Cloud Run env vars)
.env
.env.*
env.yaml
env-cloudrun.yaml
app.yaml

# IDE
.vscode
.idea
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Temporary files
tmp/
temp/

15 changes: 12 additions & 3 deletions examples-copier/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Binaries
examples-copier
code-copier
copier
*.exe
*.exe~
*.dll
Expand All @@ -19,13 +20,23 @@ vendor/
# Go workspace file
go.work

# Environment files with secrets
# Environment files with secrets (working files - create from templates in configs/)
# Working files (create from templates):
# env.yaml - App Engine deployment config (from configs/env.yaml.*)
# env-cloudrun.yaml - Cloud Run deployment config (from configs/env.yaml.*)
# .env - Local development config (from configs/.env.local.example)
env.yaml
env-cloudrun.yaml
.env
.env.local
.env.production
.env.*.local

# Explicitly keep template files in configs/ directory (these should be tracked)
!configs/env.yaml.example
!configs/env.yaml.production
!configs/.env.local.example

# Private keys
*.pem
*.key
Expand All @@ -47,5 +58,3 @@ Thumbs.db
# Temporary files
tmp/
temp/

env.yaml
38 changes: 38 additions & 0 deletions examples-copier/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Build stage
FROM golang:1.23.4-alpine AS builder

# Install build dependencies
RUN apk add --no-cache git ca-certificates

WORKDIR /app

# Copy go mod files first for better caching
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Build the binary
# CGO_ENABLED=0 for static binary (no C dependencies)
# -ldflags="-w -s" strips debug info to reduce size
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o examples-copier .

# Runtime stage
FROM alpine:latest

# Install ca-certificates for HTTPS requests
RUN apk --no-cache add ca-certificates

WORKDIR /root/

# Copy binary from builder
COPY --from=builder /app/examples-copier .

# Cloud Run sets PORT environment variable
# Our app reads it from config.Port (defaults to 8080)
EXPOSE 8080

# Run the binary
CMD ["./examples-copier"]

78 changes: 77 additions & 1 deletion examples-copier/QUICK-REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
./config-validator test-pattern -type regex -pattern "^examples/(?P<lang>[^/]+)/.*$" -file "examples/go/main.go"

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

# Initialize new config
./config-validator init -output copier-config.yaml
Expand Down Expand Up @@ -63,6 +63,18 @@ source_pattern:
pattern: "^examples/(?P<lang>[^/]+)/(?P<file>.+)$"
```

### Pattern with Exclusions
```yaml
source_pattern:
type: "prefix"
pattern: "examples/"
exclude_patterns:
- "\.gitignore$"
- "node_modules/"
- "\.env$"
- "/dist/"
```

## Path Transformations

### Built-in Variables
Expand Down Expand Up @@ -102,9 +114,73 @@ commit_strategy:
commit_message: "Update examples"
pr_title: "Update code examples"
pr_body: "Automated update"
use_pr_template: true # Fetch PR template from target repo
auto_merge: true
```

### Batch PRs by Repository
```yaml
batch_by_repo: true

batch_pr_config:
pr_title: "Update from ${source_repo}"
pr_body: |
🤖 Automated update
Files: ${file_count}
use_pr_template: true
commit_message: "Update from ${source_repo} PR #${pr_number}"
```

## Advanced Features

### Exclude Patterns
Exclude unwanted files from being copied:

```yaml
source_pattern:
type: "prefix"
pattern: "examples/"
exclude_patterns:
- "\.gitignore$" # Exclude .gitignore
- "node_modules/" # Exclude dependencies
- "\.env$" # Exclude .env files
- "\.env\\..*$" # Exclude .env.local, .env.production, etc.
- "/dist/" # Exclude build output
- "/build/" # Exclude build artifacts
- "\.test\.(js|ts)$" # Exclude test files
```

### PR Template Integration
Fetch and merge PR templates from target repos:

```yaml
commit_strategy:
type: "pull_request"
pr_body: |
🤖 Automated update
Files: ${file_count}
use_pr_template: true # Fetches .github/pull_request_template.md
```

**Result:** PR description shows:
1. Target repo's PR template (checklists, guidelines)
2. Separator (`---`)
3. Your configured content (automation info)

### Batch Configuration
When `batch_by_repo: true`, use `batch_pr_config` for accurate file counts:

```yaml
batch_by_repo: true

batch_pr_config:
pr_title: "Update from ${source_repo}"
pr_body: |
Files: ${file_count} # Accurate count across all rules
Source: ${source_repo} PR #${pr_number}
use_pr_template: true
```

## Message Templates

### Available Variables
Expand Down
91 changes: 88 additions & 3 deletions examples-copier/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# GitHub Docs Code Example Copier

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.
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.

## Features

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

### Configuration
### Local Configuration

1. **Copy environment example file**

Expand Down Expand Up @@ -96,12 +101,28 @@ Create `copier-config.yaml` in your source repository:
```yaml
source_repo: "your-org/source-repo"
source_branch: "main"
batch_by_repo: true # Optional: batch all changes into one PR per target repo

# Optional: Customize batched PR metadata
batch_pr_config:
pr_title: "Update code examples from ${source_repo}"
pr_body: |
🤖 Automated update of code examples

**Source:** ${source_repo} PR #${pr_number}
**Files:** ${file_count}
use_pr_template: true # Fetch PR template from target repos
commit_message: "Update examples from ${source_repo} PR #${pr_number}"

copy_rules:
- name: "Copy Go examples"
source_pattern:
type: "regex"
pattern: "^examples/(?P<lang>[^/]+)/(?P<category>[^/]+)/(?P<file>.+)$"
exclude_patterns: # Optional: exclude unwanted files
- "\.gitignore$"
- "node_modules/"
- "\.env$"
targets:
- repo: "your-org/target-repo"
branch: "main"
Expand All @@ -110,6 +131,8 @@ copy_rules:
type: "pull_request"
commit_message: "Update ${category} examples from ${lang}"
pr_title: "Update ${category} examples"
pr_body: "Automated update of ${lang} examples"
use_pr_template: true # Merge with target repo's PR template
auto_merge: false
deprecation_check:
enabled: true
Expand Down Expand Up @@ -203,9 +226,71 @@ commit_strategy:
commit_message: "Update examples"
pr_title: "Update ${category} examples"
pr_body: "Automated update from ${source_repo}"
use_pr_template: true # Fetch and merge PR template from target repo
auto_merge: true
```

### Advanced Features

#### Batch PRs by Repository

Combine all changes from a single source PR into one PR per target repository:

```yaml
batch_by_repo: true

batch_pr_config:
pr_title: "Update code examples from ${source_repo}"
pr_body: |
🤖 Automated update

Files: ${file_count}
Source: ${source_repo} PR #${pr_number}
use_pr_template: true
commit_message: "Update from ${source_repo} PR #${pr_number}"
```

**Benefits:**
- Single PR per target repo instead of multiple PRs
- Accurate `${file_count}` across all matched rules
- Easier review process for related changes

#### PR Template Integration

Automatically fetch and merge PR templates from target repositories:

```yaml
commit_strategy:
type: "pull_request"
pr_body: |
🤖 Automated update
Files: ${file_count}
use_pr_template: true # Fetches .github/pull_request_template.md
```

**Result:** PR description shows the target repo's template first (with checklists and guidelines), followed by your configured content.

#### File Exclusion Patterns

Exclude unwanted files from being copied:

```yaml
source_pattern:
type: "prefix"
pattern: "examples/"
exclude_patterns:
- "\.gitignore$" # Exclude .gitignore files
- "node_modules/" # Exclude dependencies
- "\.env$" # Exclude environment files
- "/dist/" # Exclude build artifacts
- "\.test\.(js|ts)$" # Exclude test files
```

**Use cases:**
- Filter out configuration files
- Exclude build artifacts and dependencies
- Skip test files or documentation

### Message Templates

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

## Deployment

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

### Google Cloud App Engine

Expand Down
2 changes: 1 addition & 1 deletion examples-copier/cmd/test-webhook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func main() {
}

func printHelp() {
fmt.Println(`Test Webhook Tool
fmt.Print(`Test Webhook Tool

Usage:
test-webhook [options]
Expand Down
Loading