Skip to content

Commit 175b5ef

Browse files
committed
feat: Add ops endpoints and refactor sync workflow
Add support for ops API endpoints following the same pattern as existing GenLayer and Debug methods. Refactor the GitHub sync workflow from monolithic structure to modular jobs with extracted utilities for better maintainability. - Add ops endpoint directory and navigation structure - Extract workflow logic into reusable shell scripts - Create centralized sync configuration - Implement matrix strategy for parallel operations - Reduce main workflow from 904 to 366 lines while maintaining identical functionality
1 parent ce14fa2 commit 175b5ef

15 files changed

Lines changed: 1370 additions & 900 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: 'Sync Files'
2+
description: 'Generic file synchronization with regex filtering - eliminates code duplication'
3+
inputs:
4+
sync_type:
5+
description: 'Type of sync operation (changelog, config, api_gen, api_debug)'
6+
required: true
7+
version:
8+
description: 'Version being synced'
9+
required: true
10+
config:
11+
description: 'Sync configuration JSON'
12+
required: true
13+
outputs:
14+
files_added:
15+
description: 'Number of files added'
16+
value: ${{ steps.sync.outputs.added }}
17+
files_updated:
18+
description: 'Number of files updated'
19+
value: ${{ steps.sync.outputs.updated }}
20+
files_deleted:
21+
description: 'Number of files deleted'
22+
value: ${{ steps.sync.outputs.deleted }}
23+
total_changes:
24+
description: 'Total number of changes'
25+
value: ${{ steps.sync.outputs.total }}
26+
runs:
27+
using: 'composite'
28+
steps:
29+
- name: Setup sync parameters
30+
id: setup
31+
shell: bash
32+
run: |
33+
# Parse configuration for this sync type
34+
CONFIG='${{ inputs.config }}'
35+
SYNC_TYPE='${{ inputs.sync_type }}'
36+
37+
# Extract paths and settings based on sync type
38+
case "$SYNC_TYPE" in
39+
"changelog")
40+
SOURCE_PATH="source-repo/$(echo "$CONFIG" | jq -r '.paths.changelog.source')"
41+
DEST_PATH="$(echo "$CONFIG" | jq -r '.paths.changelog.destination')"
42+
FILE_FILTER=".*"
43+
;;
44+
"config")
45+
SOURCE_FILE="source-repo/$(echo "$CONFIG" | jq -r '.paths.config.source')"
46+
DEST_FILE="$(echo "$CONFIG" | jq -r '.paths.config.destination')"
47+
echo "source_file=$SOURCE_FILE" >> "$GITHUB_OUTPUT"
48+
echo "dest_file=$DEST_FILE" >> "$GITHUB_OUTPUT"
49+
echo "is_single_file=true" >> "$GITHUB_OUTPUT"
50+
exit 0
51+
;;
52+
"api_gen")
53+
SOURCE_PATH="source-repo/$(echo "$CONFIG" | jq -r '.paths.api_gen.source')"
54+
DEST_PATH="$(echo "$CONFIG" | jq -r '.paths.api_gen.destination')"
55+
FILE_FILTER="$(echo "$CONFIG" | jq -r '.filters.api_gen_regex')"
56+
;;
57+
"api_debug")
58+
SOURCE_PATH="source-repo/$(echo "$CONFIG" | jq -r '.paths.api_debug.source')"
59+
DEST_PATH="$(echo "$CONFIG" | jq -r '.paths.api_debug.destination')"
60+
FILE_FILTER="$(echo "$CONFIG" | jq -r '.filters.api_debug_regex')"
61+
;;
62+
*)
63+
echo "::error::Unknown sync type: $SYNC_TYPE"
64+
exit 1
65+
;;
66+
esac
67+
68+
echo "source_path=$SOURCE_PATH" >> "$GITHUB_OUTPUT"
69+
echo "dest_path=$DEST_PATH" >> "$GITHUB_OUTPUT"
70+
echo "file_filter=$FILE_FILTER" >> "$GITHUB_OUTPUT"
71+
echo "is_single_file=false" >> "$GITHUB_OUTPUT"
72+
73+
- name: Sync files
74+
id: sync
75+
shell: bash
76+
run: |
77+
set -euo pipefail
78+
79+
# Load sync utilities
80+
source .github/scripts/sync-files.sh
81+
82+
REPORT_FILE="${{ runner.temp }}/sync_report_${{ inputs.sync_type }}.md"
83+
84+
# Handle single file vs directory sync
85+
if [[ "${{ steps.setup.outputs.is_single_file }}" == "true" ]]; then
86+
# Special handling for config file
87+
source .github/scripts/config-processor.sh
88+
process_config_file \
89+
"${{ steps.setup.outputs.source_file }}" \
90+
"${{ steps.setup.outputs.dest_file }}" \
91+
"$REPORT_FILE"
92+
else
93+
# Standard file sync
94+
sync_files \
95+
"${{ steps.setup.outputs.source_path }}" \
96+
"${{ steps.setup.outputs.dest_path }}" \
97+
"${{ steps.setup.outputs.file_filter }}" \
98+
"${{ inputs.sync_type }}" \
99+
"$REPORT_FILE"
100+
fi
101+
102+
echo "Sync completed for ${{ inputs.sync_type }}"
103+
104+
# Store report content for later use
105+
if [[ -f "$REPORT_FILE" ]]; then
106+
echo "report_content<<EOF" >> "$GITHUB_OUTPUT"
107+
cat "$REPORT_FILE" >> "$GITHUB_OUTPUT"
108+
echo "EOF" >> "$GITHUB_OUTPUT"
109+
fi

.github/config/sync-config.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Centralized configuration for documentation sync operations
2+
# This replaces scattered hardcoded values throughout the workflow
3+
4+
repositories:
5+
source:
6+
owner: genlayerlabs
7+
name: genlayer-node
8+
sparse_checkout:
9+
- docs
10+
- configs/node/config.yaml.example
11+
12+
paths:
13+
changelog:
14+
source: docs/changelog
15+
destination: content/validators/changelog
16+
description: "Validator changelog files"
17+
18+
config:
19+
source: configs/node/config.yaml.example
20+
destination: content/validators/config.yaml
21+
description: "Node configuration template"
22+
23+
api_gen:
24+
source: docs/api/rpc
25+
destination: pages/api-references/genlayer-node/gen
26+
description: "GenLayer API method documentation"
27+
28+
api_debug:
29+
source: docs/api/rpc
30+
destination: pages/api-references/genlayer-node/debug
31+
description: "Debug API method documentation"
32+
33+
filters:
34+
api_gen_regex: 'gen_(?!dbg_).*'
35+
api_debug_regex: 'gen_dbg_.*'
36+
37+
scripts:
38+
post_sync:
39+
- name: "Generate changelog"
40+
command: "npm run node-generate-changelog"
41+
description: "Process and generate changelog documentation"
42+
43+
- name: "Update setup guide"
44+
command: "npm run node-update-setup-guide"
45+
description: "Update version references in setup guide"
46+
47+
- name: "Update config in setup guide"
48+
command: "npm run node-update-config"
49+
description: "Update configuration in setup guide"
50+
51+
- name: "Generate API docs"
52+
command: "npm run node-generate-api-docs"
53+
description: "Generate API documentation from individual method files"
54+
55+
defaults:
56+
version: "latest"
57+
changelog_path: "docs/changelog"
58+
api_gen_path: "docs/api/rpc"
59+
api_debug_path: "docs/api/rpc"
60+
61+
git:
62+
branch_prefix: "docs/node/"
63+
commit_message_template: |
64+
docs: Sync documentation from node repository {version}
65+
66+
- Source: genlayerlabs/genlayer-node@{version}
67+
- Version: {version}
68+
- Total changes: {total_changes}
69+
- Added: {total_added} files
70+
- Updated: {total_updated} files
71+
- Deleted: {total_deleted} files
72+
73+
pr:
74+
title_template: "docs: Sync documentation from genlayer-node {version}"
75+
labels:
76+
- "documentation"
77+
- "node"
78+
base_branch: "main"

.github/scripts/config-loader.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Configuration loading utilities
5+
# Loads and validates the centralized sync configuration
6+
7+
# Load sync configuration from YAML file
8+
load_sync_config() {
9+
local config_file=".github/config/sync-config.yml"
10+
11+
if [[ ! -f "$config_file" ]]; then
12+
echo "::error::Sync configuration file not found: $config_file"
13+
return 1
14+
fi
15+
16+
echo "📋 Loading sync configuration from $config_file"
17+
18+
# Convert YAML to JSON for easier parsing in GitHub Actions
19+
local config_json
20+
config_json=$(python3 -c "
21+
import yaml, json, sys
22+
try:
23+
with open('$config_file', 'r') as f:
24+
config = yaml.safe_load(f)
25+
print(json.dumps(config))
26+
except Exception as e:
27+
print(f'Error loading config: {e}', file=sys.stderr)
28+
sys.exit(1)
29+
")
30+
31+
if [[ $? -ne 0 ]]; then
32+
echo "::error::Failed to parse sync configuration"
33+
return 1
34+
fi
35+
36+
# Output the config for use in other jobs
37+
echo "config<<EOF" >> "$GITHUB_OUTPUT"
38+
echo "$config_json" >> "$GITHUB_OUTPUT"
39+
echo "EOF" >> "$GITHUB_OUTPUT"
40+
41+
echo "✅ Sync configuration loaded successfully"
42+
return 0
43+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Configuration file processing utilities
5+
# Extracted from the complex config processing logic in the workflow
6+
7+
# Process and sanitize config file
8+
process_config_file() {
9+
local source_config="$1"
10+
local dest_config="$2"
11+
local report_file="$3"
12+
13+
echo "" >> "$report_file"
14+
echo "## Config File Sync" >> "$report_file"
15+
echo "" >> "$report_file"
16+
17+
if [[ ! -f "$source_config" ]]; then
18+
printf -- "- Source config file not found at: \`%s\`\n" "${source_config#source-repo/}" >> "$report_file"
19+
echo "config_updated=0" >> "$GITHUB_OUTPUT"
20+
echo "::warning::Config file not found: $source_config"
21+
return 0
22+
fi
23+
24+
echo "✓ Found config file at: $source_config"
25+
mkdir -p "$(dirname "$dest_config")"
26+
27+
# Create a temporary file for sanitized config
28+
local temp_config
29+
temp_config=$(mktemp)
30+
31+
# Copy and sanitize the config
32+
cp "$source_config" "$temp_config"
33+
34+
echo "🔧 Sanitizing config file..."
35+
36+
# Replace actual URLs with TODO placeholders
37+
sed -i.bak 's|zksyncurl: *"[^"]*"|zksyncurl: "TODO: Set your GenLayer Chain ZKSync HTTP RPC URL here"|' "$temp_config"
38+
sed -i.bak 's|zksyncwebsocketurl: *"[^"]*"|zksyncwebsocketurl: "TODO: Set your GenLayer Chain ZKSync WebSocket RPC URL here"|' "$temp_config"
39+
40+
# Remove backup files
41+
rm -f "${temp_config}.bak"
42+
43+
# Remove node.dev sections using Python for reliable YAML parsing
44+
if [[ -f ".github/scripts/sanitize-config.py" ]]; then
45+
echo "🐍 Running Python sanitization script..."
46+
python3 .github/scripts/sanitize-config.py "$temp_config"
47+
local sanitize_exit_code=$?
48+
49+
if [[ $sanitize_exit_code -ne 0 ]]; then
50+
echo "::error::Config sanitization failed!"
51+
rm -f "$temp_config"
52+
return 1
53+
fi
54+
else
55+
echo "::warning::Sanitization script not found, skipping dev section removal"
56+
fi
57+
58+
# Check if the config has changed
59+
if [[ -f "$dest_config" ]]; then
60+
if ! cmp -s "$temp_config" "$dest_config"; then
61+
cp "$temp_config" "$dest_config"
62+
echo "- Updated: \`config.yaml\` (sanitized)" >> "$report_file"
63+
echo "config_updated=1" >> "$GITHUB_OUTPUT"
64+
echo "✅ Config file was updated"
65+
66+
# Output standard metrics for workflow
67+
echo "added=0" >> "$GITHUB_OUTPUT"
68+
echo "updated=1" >> "$GITHUB_OUTPUT"
69+
echo "deleted=0" >> "$GITHUB_OUTPUT"
70+
echo "total=1" >> "$GITHUB_OUTPUT"
71+
echo "1" > "${RUNNER_TEMP}/changes_config.txt"
72+
else
73+
echo "- No changes to \`config.yaml\`" >> "$report_file"
74+
echo "config_updated=0" >> "$GITHUB_OUTPUT"
75+
echo "ℹ️ Config file unchanged"
76+
77+
# Output zero metrics
78+
echo "added=0" >> "$GITHUB_OUTPUT"
79+
echo "updated=0" >> "$GITHUB_OUTPUT"
80+
echo "deleted=0" >> "$GITHUB_OUTPUT"
81+
echo "total=0" >> "$GITHUB_OUTPUT"
82+
echo "0" > "${RUNNER_TEMP}/changes_config.txt"
83+
fi
84+
else
85+
cp "$temp_config" "$dest_config"
86+
echo "- Added: \`config.yaml\` (sanitized)" >> "$report_file"
87+
echo "config_updated=1" >> "$GITHUB_OUTPUT"
88+
echo "✅ Config file was created"
89+
90+
# Output standard metrics for workflow
91+
echo "added=1" >> "$GITHUB_OUTPUT"
92+
echo "updated=0" >> "$GITHUB_OUTPUT"
93+
echo "deleted=0" >> "$GITHUB_OUTPUT"
94+
echo "total=1" >> "$GITHUB_OUTPUT"
95+
echo "1" > "${RUNNER_TEMP}/changes_config.txt"
96+
fi
97+
98+
# Verify final config structure
99+
verify_config_structure "$dest_config"
100+
101+
# Clean up temp file
102+
rm -f "$temp_config"
103+
}
104+
105+
# Verify config file has expected structure
106+
verify_config_structure() {
107+
local config_file="$1"
108+
109+
echo "🔍 Verifying config structure..."
110+
111+
local missing_sections=()
112+
113+
if ! grep -q "^node:" "$config_file"; then
114+
missing_sections+=("node")
115+
fi
116+
117+
if ! grep -q "^consensus:" "$config_file"; then
118+
missing_sections+=("consensus")
119+
fi
120+
121+
if ! grep -q "^genvm:" "$config_file"; then
122+
missing_sections+=("genvm")
123+
fi
124+
125+
if ! grep -q "^metrics:" "$config_file"; then
126+
missing_sections+=("metrics")
127+
fi
128+
129+
if [[ ${#missing_sections[@]} -gt 0 ]]; then
130+
echo "::warning::Missing config sections: ${missing_sections[*]}"
131+
else
132+
echo "✅ All expected config sections found"
133+
fi
134+
135+
# Check for sensitive sections that should be removed
136+
if grep -q "^\s*dev:" "$config_file"; then
137+
echo "::error::Dev section still present in config!"
138+
return 1
139+
fi
140+
141+
# Check for TODO placeholders
142+
if grep -q "TODO:" "$config_file"; then
143+
echo "✅ TODO placeholders found in config"
144+
else
145+
echo "::warning::No TODO placeholders found in config"
146+
fi
147+
148+
echo "📊 Config file size: $(wc -c < "$config_file") bytes"
149+
}

0 commit comments

Comments
 (0)