Skip to content

Commit a036911

Browse files
committed
Add GitHub Actions workflows for module tagging
- Add tag-release.yml: workflow_dispatch for creating module tags - Add list-tags.yml: workflow for managing and listing existing tags - Add comprehensive README.md with usage instructions - Supports all modules: add-header, cors, rate-limit - Includes validation, dry-run mode, and safety features
1 parent fdee240 commit a036911

3 files changed

Lines changed: 475 additions & 0 deletions

File tree

.github/workflows/README.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# GitHub Actions Workflows for Go Multi-Major Modules
2+
3+
This directory contains GitHub Actions workflows for managing tags and releases for the Go multi-major modules in this repository.
4+
5+
## Workflows
6+
7+
### 1. Create Module Tags (`tag-release.yml`)
8+
9+
**Purpose**: Create Git tags for Go module releases with `workflow_dispatch` trigger.
10+
11+
**Trigger**: Manual via GitHub Actions UI
12+
13+
**Inputs**:
14+
- `policy_name`: Choose the module (`add-header`, `cors`, `rate-limit`)
15+
- `version`: Choose the major version (`v1`, `v2`, `v3`)
16+
- `patch_version`: Specify patch version (e.g., `0.0`, `0.1`, `1.0`)
17+
- `dry_run`: Preview what would be tagged without creating tags
18+
19+
**What it does**:
20+
1. Validates the module exists and has a valid `go.mod`
21+
2. Runs tests if they exist
22+
3. Checks if the tag already exists
23+
4. Creates an annotated Git tag with format: `{policy_name}/{version}.{patch_version}`
24+
5. Pushes the tag to the repository
25+
26+
**Example tags created**:
27+
- `add-header/v1.0.0`
28+
- `cors/v2.1.0`
29+
- `rate-limit/v3.0.1`
30+
31+
### 2. List Module Tags (`list-tags.yml`)
32+
33+
**Purpose**: List and validate existing module tags.
34+
35+
**Trigger**: Manual via GitHub Actions UI
36+
37+
**Inputs**:
38+
- `policy_name`: Filter by specific module (optional)
39+
- `action`: Choose action (`list`, `list-latest`, `validate-modules`)
40+
41+
**Actions**:
42+
- `list`: Show all tags or tags for a specific module
43+
- `list-latest`: Show the latest tag for each major version of each module
44+
- `validate-modules`: Validate all modules and their go.mod files
45+
46+
## Usage
47+
48+
### Creating a New Release
49+
50+
1. Go to **Actions** tab in your GitHub repository
51+
2. Select **"Create Module Tags"** workflow
52+
3. Click **"Run workflow"**
53+
4. Fill in the parameters:
54+
- **Policy name**: Select the module you want to release
55+
- **Version**: Select the major version
56+
- **Patch version**: Enter the patch version (e.g., "0.0" for first release, "0.1" for patch)
57+
- **Dry run**: Check this to preview without creating tags
58+
5. Click **"Run workflow"**
59+
60+
### Example Scenarios
61+
62+
#### First release of add-header v1
63+
- Policy name: `add-header`
64+
- Version: `v1`
65+
- Patch version: `0.0`
66+
- Result: Creates tag `add-header/v1.0.0`
67+
68+
#### Bug fix for rate-limit v2
69+
- Policy name: `rate-limit`
70+
- Version: `v2`
71+
- Patch version: `1.1` (if previous was v2.1.0)
72+
- Result: Creates tag `rate-limit/v2.1.1`
73+
74+
#### Preview without creating tags
75+
- Enable "Dry run" to see what would be created
76+
77+
### Viewing Existing Tags
78+
79+
1. Go to **Actions** tab
80+
2. Select **"List Module Tags"** workflow
81+
3. Choose action:
82+
- **list**: See all tags
83+
- **list-latest**: See latest tag per major version
84+
- **validate-modules**: Check all modules are valid
85+
86+
## Tag Format
87+
88+
Tags follow the format: `{module-name}/{major-version}.{patch-version}`
89+
90+
Examples:
91+
- `add-header/v1.0.0`
92+
- `add-header/v1.0.1`
93+
- `add-header/v2.0.0`
94+
- `cors/v1.0.0`
95+
- `rate-limit/v3.1.0`
96+
97+
## Go Module Usage
98+
99+
After creating tags, users can import specific versions:
100+
101+
```go
102+
// Import specific version
103+
import "github.com/DakshithaS/go-multi-major-modules/add-header/v1"
104+
105+
// Or get specific tagged version
106+
// go get github.com/DakshithaS/go-multi-major-modules/add-header/v1@v1.0.0
107+
```
108+
109+
## Validation
110+
111+
The workflows perform several validations:
112+
- ✅ Module directory exists
113+
-`go.mod` file exists and is valid
114+
- ✅ Module name in `go.mod` matches expected pattern
115+
- ✅ Tests pass (if present)
116+
- ✅ Tag doesn't already exist
117+
- ✅ Git repository is clean
118+
119+
## Security
120+
121+
The workflows use:
122+
- `contents: write` permission for creating tags
123+
- `contents: read` permission for listing tags
124+
- GitHub Actions bot for commits
125+
- No external dependencies beyond official GitHub actions
126+
127+
## Troubleshooting
128+
129+
### Tag already exists
130+
If a tag already exists, the workflow will fail and show existing tags for the module.
131+
132+
### Module validation fails
133+
Check that:
134+
- The module directory exists
135+
- `go.mod` file is present and valid
136+
- Tests pass (if any exist)
137+
- Module name in `go.mod` matches expected pattern
138+
139+
### Permission denied
140+
Ensure the repository has Actions enabled and the workflow has necessary permissions.

.github/workflows/list-tags.yml

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
name: List Module Tags
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
policy_name:
7+
description: 'Policy/Module name (optional - leave empty for all modules)'
8+
required: false
9+
type: choice
10+
options:
11+
- ''
12+
- add-header
13+
- cors
14+
- rate-limit
15+
action:
16+
description: 'Action to perform'
17+
required: true
18+
type: choice
19+
default: 'list'
20+
options:
21+
- list
22+
- list-latest
23+
- validate-modules
24+
25+
jobs:
26+
manage-tags:
27+
runs-on: ubuntu-latest
28+
permissions:
29+
contents: read
30+
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@v4
34+
with:
35+
fetch-depth: 0 # Fetch all history and tags
36+
37+
- name: Set up Go
38+
uses: actions/setup-go@v4
39+
with:
40+
go-version: '1.21'
41+
42+
- name: List all module tags
43+
if: ${{ github.event.inputs.action == 'list' && github.event.inputs.policy_name == '' }}
44+
run: |
45+
echo "🏷️ All module tags in repository:"
46+
echo ""
47+
48+
# Get all tags and group by module
49+
for module in add-header cors rate-limit; do
50+
echo "📦 $module:"
51+
tags=$(git tag -l | grep "^$module/" | sort -V || true)
52+
if [ -z "$tags" ]; then
53+
echo " No tags found"
54+
else
55+
echo "$tags" | sed 's/^/ /'
56+
fi
57+
echo ""
58+
done
59+
60+
- name: List specific module tags
61+
if: ${{ github.event.inputs.action == 'list' && github.event.inputs.policy_name != '' }}
62+
run: |
63+
POLICY_NAME="${{ github.event.inputs.policy_name }}"
64+
echo "🏷️ Tags for module: $POLICY_NAME"
65+
echo ""
66+
67+
tags=$(git tag -l | grep "^$POLICY_NAME/" | sort -V || true)
68+
if [ -z "$tags" ]; then
69+
echo " No tags found for $POLICY_NAME"
70+
else
71+
echo "$tags" | while read tag; do
72+
# Get tag date and message
73+
tag_date=$(git log -1 --format=%ai $tag 2>/dev/null || echo "Unknown date")
74+
echo " $tag (created: $tag_date)"
75+
done
76+
fi
77+
78+
- name: List latest tags for each module
79+
if: ${{ github.event.inputs.action == 'list-latest' }}
80+
run: |
81+
echo "🚀 Latest tags for each module:"
82+
echo ""
83+
84+
for module in add-header cors rate-limit; do
85+
echo "📦 $module:"
86+
87+
# Find latest tag for each major version
88+
for version in v1 v2 v3; do
89+
latest=$(git tag -l | grep "^$module/$version\." | sort -V | tail -1 || true)
90+
if [ -n "$latest" ]; then
91+
tag_date=$(git log -1 --format=%ai $latest 2>/dev/null || echo "Unknown date")
92+
echo " $version: $latest (created: $tag_date)"
93+
else
94+
echo " $version: No releases"
95+
fi
96+
done
97+
echo ""
98+
done
99+
100+
- name: Validate all modules
101+
if: ${{ github.event.inputs.action == 'validate-modules' }}
102+
run: |
103+
echo "🔍 Validating all modules..."
104+
echo ""
105+
106+
errors=0
107+
108+
for module in add-header cors rate-limit; do
109+
for version in v1 v2 v3; do
110+
module_path="$module/$version"
111+
echo "📦 Checking $module_path..."
112+
113+
if [ ! -d "$module_path" ]; then
114+
echo " ❌ Directory does not exist"
115+
((errors++))
116+
continue
117+
fi
118+
119+
if [ ! -f "$module_path/go.mod" ]; then
120+
echo " ❌ go.mod not found"
121+
((errors++))
122+
continue
123+
fi
124+
125+
cd "$module_path"
126+
127+
# Validate go.mod
128+
if ! go mod verify 2>/dev/null; then
129+
echo " ❌ go.mod verification failed"
130+
((errors++))
131+
cd ../..
132+
continue
133+
fi
134+
135+
# Check if module name in go.mod matches expected
136+
expected_module="github.com/DakshithaS/go-multi-major-modules/$module_path"
137+
actual_module=$(grep '^module' go.mod | cut -d' ' -f2)
138+
if [ "$actual_module" != "$expected_module" ]; then
139+
echo " ⚠️ Module name mismatch: expected '$expected_module', got '$actual_module'"
140+
((errors++))
141+
fi
142+
143+
# Run tests if they exist
144+
if ls *_test.go 1> /dev/null 2>&1; then
145+
if go test ./... > /dev/null 2>&1; then
146+
echo " ✅ Tests passed"
147+
else
148+
echo " ❌ Tests failed"
149+
((errors++))
150+
fi
151+
else
152+
echo " ⚠️ No tests found"
153+
fi
154+
155+
cd ../..
156+
done
157+
done
158+
159+
echo ""
160+
if [ $errors -eq 0 ]; then
161+
echo "✅ All modules validated successfully!"
162+
else
163+
echo "❌ Found $errors errors during validation"
164+
exit 1
165+
fi

0 commit comments

Comments
 (0)