Skip to content

Commit 7d1edd9

Browse files
committed
ai suggestions
1 parent 0ed6970 commit 7d1edd9

File tree

2 files changed

+286
-0
lines changed

2 files changed

+286
-0
lines changed

.github/workflows/README.md

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
# GitHub Workflows Documentation
2+
3+
Comprehensive guide to ev-node CI/CD workflows, orchestration, and tag-based release process.
4+
5+
## Table of Contents
6+
7+
- [Workflow Architecture](#workflow-architecture)
8+
- [CI Workflow](#ci-workflow)
9+
- [Release Workflow](#release-workflow)
10+
- [Tag-Based Release Process](#tag-based-release-process)
11+
- [Troubleshooting](#troubleshooting)
12+
13+
## Workflow Architecture
14+
15+
```
16+
┌──────────────────────────────────────────────────────────────┐
17+
│ Trigger Events │
18+
│ • push to main • pull_request • merge_group • tags │
19+
└───────────────────────────┬──────────────────────────────────┘
20+
21+
┌───────────────────┴────────────────────┐
22+
│ │
23+
v v
24+
┌───────────────────┐ ┌────────────────────┐
25+
│ CI Workflow │ │ Release Workflow │
26+
│ (ci.yml) │ │ (release.yml) │
27+
│ │ │ │
28+
│ 1. Image Tag │ │ Trigger: Tag │
29+
│ Generation │ │ **/v*.*.* │
30+
│ • PR: pr-# │ │ │
31+
│ • Branch: ref │ │ 1. Parse Tag │
32+
│ │ │ • Validate │
33+
│ 2. Parallel: │ │ • Extract │
34+
│ • Lint │ │ │
35+
│ • Docker │ │ 2. Build & Push │
36+
│ • Tests │ │ • Multi-arch │
37+
│ • Proto │ │ • Version tag │
38+
│ │ │ • Latest tag │
39+
│ 3. Sequential: │ │ │
40+
│ • Docker E2E │ │ │
41+
└───────────────────┘ └────────────────────┘
42+
```
43+
44+
## CI Workflow
45+
46+
**Entry Point:** `ci.yml` - Orchestrates all CI processes
47+
48+
**Triggers:** `push` to main | `pull_request` | `merge_group`
49+
50+
### Image Tag Generation
51+
52+
First job generates consistent Docker tags for all downstream jobs:
53+
- **PRs:** `pr-{number}` (e.g., `pr-123`)
54+
- **Branches:** Sanitized ref name (e.g., `main`)
55+
56+
### Parallel Jobs
57+
58+
**Lint** (`lint.yml`) - Code quality checks:
59+
- golangci-lint, hadolint, yamllint, markdown-lint, goreleaser-check
60+
61+
**Docker** (`docker.yml`) - Image builds:
62+
- Multi-platform (linux/amd64, linux/arm64)
63+
- Pushes to GHCR with generated tag
64+
- Skips for merge groups (uses PR cache)
65+
66+
**Tests** (`test.yml`) - Comprehensive testing:
67+
- Build all binaries, Go mod tidy check
68+
- Unit tests, Integration tests, E2E tests, EVM tests
69+
- Combined coverage upload to Codecov
70+
71+
**Proto** (`proto.yml`) - Protobuf validation using Buf
72+
73+
### Sequential Jobs
74+
75+
**Docker E2E Tests** (`docker-tests.yml`):
76+
- Waits for Docker build completion
77+
- Runs E2E and upgrade tests using built images
78+
- Can be manually triggered via `workflow_dispatch`
79+
80+
### Dependencies
81+
82+
```
83+
determine-image-tag
84+
├─→ lint
85+
├─→ docker ──→ docker-tests
86+
├─→ test
87+
└─→ proto
88+
```
89+
90+
## Release Workflow
91+
92+
**Entry Point:** `release.yml` - Automated Docker image releases
93+
94+
**Triggers:** Tag push matching `**/v*.*.*` (e.g., `evm/single/v0.2.0`)
95+
96+
### Parse Release Tag
97+
98+
Extracts and validates:
99+
```yaml
100+
Input: evm/single/v0.2.0
101+
Output:
102+
app-path: evm/single
103+
version: v0.2.0
104+
image-name: ev-node-evm-single
105+
dockerfile: apps/evm/single/Dockerfile
106+
```
107+
108+
**Validation:**
109+
- ✅ App directory exists: `./apps/{app-path}`
110+
- ✅ Dockerfile exists: `apps/{app-path}/Dockerfile`
111+
- ✅ Tag matches: `**/v*.*.*`
112+
- ✅ Semantic versioning format
113+
114+
### Build and Push
115+
116+
- Multi-platform build (amd64, arm64)
117+
- Publishes to GHCR:
118+
- `ghcr.io/{owner}/ev-node-{app}:v0.2.0` (version tag)
119+
- `ghcr.io/{owner}/ev-node-{app}:latest` (latest tag)
120+
121+
## Tag-Based Release Process
122+
123+
### Tag Format
124+
125+
**Pattern:** `{app-path}/v{major}.{minor}.{patch}`
126+
127+
Maps directly to `./apps/` directory structure:
128+
129+
| Tag | App Path | Version | Image Name |
130+
|-----|----------|---------|------------|
131+
| `evm/single/v0.2.0` | `evm/single` | `v0.2.0` | `ev-node-evm-single` |
132+
| `testapp/v1.0.0` | `testapp` | `v1.0.0` | `ev-node-testapp` |
133+
| `grpc/single/v2.1.3` | `grpc/single` | `v2.1.3` | `ev-node-grpc-single` |
134+
135+
### Release Steps
136+
137+
#### 1. Pre-Release Checklist
138+
- [ ] Changes committed and pushed to `main`
139+
- [ ] CI passes
140+
- [ ] CHANGELOG.md updated
141+
- [ ] Dockerfile exists in app directory
142+
143+
#### 2. Create Tag
144+
145+
```bash
146+
# Annotated tag with release notes
147+
git tag -a evm/single/v0.2.0 -m "Release EVM single v0.2.0
148+
149+
Features:
150+
- Added feature X
151+
- Improved performance Y
152+
153+
Bug fixes:
154+
- Fixed issue Z
155+
"
156+
157+
git push origin evm/single/v0.2.0
158+
```
159+
160+
#### 3. Automated Process
161+
162+
Workflow automatically:
163+
1. Validates tag and app structure
164+
2. Builds multi-platform images
165+
3. Publishes to GHCR with version + latest tags
166+
167+
#### 4. Verify
168+
169+
```bash
170+
docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0
171+
docker run ghcr.io/evstack/ev-node-evm-single:v0.2.0 --version
172+
```
173+
174+
### Multiple Releases
175+
176+
```bash
177+
# Individual tags
178+
git tag evm/single/v0.2.0 && git push origin evm/single/v0.2.0
179+
git tag testapp/v1.0.0 && git push origin testapp/v1.0.0
180+
181+
# Multiple at once
182+
git push origin evm/single/v0.2.0 testapp/v1.0.0
183+
```
184+
185+
### Semantic Versioning
186+
187+
- **MAJOR (v2.0.0):** Breaking changes
188+
- **MINOR (v1.1.0):** New features, backward compatible
189+
- **PATCH (v1.0.1):** Bug fixes, backward compatible
190+
191+
### Rollback
192+
193+
```bash
194+
# Delete tag
195+
git tag -d evm/single/v0.2.0
196+
git push origin :refs/tags/evm/single/v0.2.0
197+
198+
# Fix and recreate
199+
git tag -a evm/single/v0.2.0 -m "Release message"
200+
git push origin evm/single/v0.2.0
201+
```
202+
203+
### Best Practices
204+
205+
1. Use annotated tags with descriptive messages
206+
2. Update CHANGELOG.md before tagging
207+
3. Ensure CI passes on main
208+
4. Test locally before release
209+
5. Document breaking changes
210+
6. Version tags are immutable references
211+
7. Latest tag points to most recent release
212+
213+
### Adding New Apps
214+
215+
1. Create directory: `apps/new-app/Dockerfile`
216+
2. Add to CI yaml (if needed):
217+
```yaml
218+
apps: [{"name": "ev-node-new-app", "dockerfile": "apps/new-app/Dockerfile"}]
219+
```
220+
3. Create tag: `git tag new-app/v1.0.0 && git push origin new-app/v1.0.0`
221+
222+
## Environment & Secrets
223+
224+
### Variables
225+
226+
| Variable | Description | Example |
227+
|----------|-------------|---------|
228+
| `EV_NODE_IMAGE_REPO` | GHCR repository | `ghcr.io/evstack` |
229+
| `EV_NODE_IMAGE_TAG` | Image tag | `pr-123`, `main` |
230+
231+
### Secrets
232+
233+
| Secret | Description | Used By |
234+
|--------|-------------|---------|
235+
| `GITHUB_TOKEN` | GHCR authentication | Docker workflows |
236+
| `CODECOV_TOKEN` | Coverage upload | Test workflow |
237+
238+
## Troubleshooting
239+
240+
### Release Errors
241+
242+
**"App directory does not exist"**
243+
- Tag must match app path: `apps/evm/single/` → `evm/single/v0.2.0`
244+
245+
**"Dockerfile not found"**
246+
- Verify `apps/{app-path}/Dockerfile` exists
247+
248+
**"Invalid tag format"**
249+
- Use `evm/single/v0.2.0` not `evm/single/0.2.0`
250+
251+
### CI Errors
252+
253+
**Docker E2E "image not found"**
254+
- Wait for Docker build job completion
255+
256+
**Coverage upload fails**
257+
- Verify `CODECOV_TOKEN` in repository settings
258+
259+
**Lint failures**
260+
- Run locally: `make lint`
261+
262+
### Manual Triggers
263+
264+
**Docker E2E tests:**
265+
```
266+
GitHub → Actions → "Docker Tests" → Run workflow
267+
Enter tag: pr-123, main, v0.2.0
268+
```
269+
270+
**Check images:**
271+
```bash
272+
gh api /orgs/evstack/packages/container/ev-node-evm-single/versions
273+
docker pull ghcr.io/evstack/ev-node-evm-single:v0.2.0
274+
```
275+
276+
## Additional Resources
277+
278+
- **Complete Release Guide:** [RELEASE.md](../RELEASE.md)
279+
- **Quick Start:** [RELEASE_QUICK_START.md](../RELEASE_QUICK_START.md)
280+
- **GitHub Actions:** https://docs.github.com/en/actions
281+
- **Semantic Versioning:** https://semver.org/
282+
- **GHCR Docs:** https://docs.github.com/en/packages

.github/workflows/release.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ jobs:
2626
run: |
2727
# Get the previous tag
2828
CURRENT_TAG="${{ github.ref_name }}"
29+
if [[ ! "$CURRENT_TAG" =~ ^[a-zA-Z0-9/_.-]+$ ]]; then
30+
echo "::error::Invalid tag format: $CURRENT_TAG"
31+
exit 1
32+
fi
2933
PREV_TAG=$(git tag --sort=-version:refname | grep -A1 "^${CURRENT_TAG}$" | tail -1)
3034
3135
if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "$CURRENT_TAG" ]; then

0 commit comments

Comments
 (0)