@@ -2,18 +2,14 @@ name: Build and Release Sample Artifacts
22
33on :
44 push :
5- branches : [feat/zip-script]
5+ branches : [feat/zip-script] # change to 'main' for production
66 paths :
7- - ' */*/README.md'
8- - ' */*/*.py'
9- - ' */*/*.js'
10- - ' */*/*.ts'
11- - ' */*/*.jsx'
12- - ' */*/*.tsx'
13- - ' */*/*.json'
14- - ' */*/*.md'
15- - ' */*/*.yml'
16- - ' */*/*.yaml'
7+ - ' */*/release-config.yml'
8+ - ' */**'
9+ - ' !.github/**'
10+ - ' !*.md'
11+ - ' !LICENSE'
12+ - ' !.gitignore'
1713 workflow_dispatch :
1814 inputs :
1915 force_rebuild :
@@ -44,77 +40,159 @@ jobs:
4440 - name : Create artifacts directory
4541 run : mkdir -p artifacts
4642
47- - name : Validate repository structure
43+ - name : Find and validate release configurations
4844 run : |
49- echo "🔍 Validating repository structure ..."
45+ echo "🔍 Finding release configurations ..."
5046
51- SAMPLE_DIRS =$(find . -maxdepth 2 -type d -path "./*/*" | grep -v " .git" | sort)
47+ RELEASE_CONFIGS =$(find . -name "release-config.yml" -not -path "./.git/* " | sort)
5248
53- if [ -z "$SAMPLE_DIRS" ]; then
54- echo "❌ No sample directories found!"
49+ if [ -z "$RELEASE_CONFIGS" ]; then
50+ echo "❌ No release-config.yml files found!"
51+ echo "📂 Available directories:"
52+ find . -type d -maxdepth 3 | head -20
5553 exit 1
5654 fi
5755
58- echo "✅ Found sample directories :"
59- echo "$SAMPLE_DIRS "
56+ echo "✅ Found release configurations :"
57+ echo "$RELEASE_CONFIGS "
6058
61- - name : Build quickstart packages
59+ # Validate each config file
60+ for config_file in $RELEASE_CONFIGS; do
61+ echo "📄 Validating: $config_file"
62+
63+ # Check if it has required fields and included: true
64+ if grep -q "^category:" "$config_file" && grep -q "^framework:" "$config_file"; then
65+ INCLUDED=$(grep "^included:" "$config_file" | sed 's/included: *//' | tr -d ' ')
66+ if [ "$INCLUDED" = "true" ]; then
67+ echo " ✅ Valid configuration (included: true)"
68+ else
69+ echo " ⏭️ Skipping (included: $INCLUDED)"
70+ fi
71+ else
72+ echo " ❌ Missing required fields (category, framework) in $config_file"
73+ exit 1
74+ fi
75+ done
76+
77+ - name : Check if changed files are in configured directories
6278 run : |
63- echo "📦 Building sample packages..."
79+ echo "🔍 Checking if changes affect configured quickstarts..."
80+
81+ # Get list of directories with release-config.yml
82+ CONFIG_DIRS=$(find . -name "release-config.yml" -not -path "./.git/*" -exec dirname {} \; | sort)
83+
84+ echo "📂 Directories with release-config.yml:"
85+ echo "$CONFIG_DIRS"
86+
87+ # If this is a manual trigger, rebuild all
88+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
89+ echo "🔄 Manual trigger - will rebuild all configured samples"
90+ echo "SHOULD_BUILD=true" >> $GITHUB_ENV
91+ exit 0
92+ fi
93+
94+ # Check if any changed files are in directories with release-config.yml
95+ CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "")
96+
97+ if [ -z "$CHANGED_FILES" ]; then
98+ echo "📝 No changed files detected, building all"
99+ echo "SHOULD_BUILD=true" >> $GITHUB_ENV
100+ exit 0
101+ fi
102+
103+ echo "📝 Changed files:"
104+ echo "$CHANGED_FILES"
105+
106+ SHOULD_BUILD=false
107+
108+ for config_dir in $CONFIG_DIRS; do
109+ # Remove leading ./
110+ clean_dir=$(echo "$config_dir" | sed 's|^\./||')
111+
112+ # Check if any changed file is in this directory
113+ if echo "$CHANGED_FILES" | grep -q "^$clean_dir/"; then
114+ echo "✅ Changes detected in configured directory: $clean_dir"
115+ SHOULD_BUILD=true
116+ break
117+ fi
118+ done
119+
120+ if [ "$SHOULD_BUILD" = "true" ]; then
121+ echo "🔄 Will rebuild artifacts (changes in configured directories)"
122+ echo "SHOULD_BUILD=true" >> $GITHUB_ENV
123+ else
124+ echo "⏭️ No changes in configured directories, skipping build"
125+ echo "SHOULD_BUILD=false" >> $GITHUB_ENV
126+ fi
64127
65- find . -maxdepth 2 -type d -path "./*/*" | grep -v ".git" | while read sample_dir; do
66- if [ -d "$sample_dir" ] && [ -f "$sample_dir/README.md" ]; then
67- CATEGORY=$(basename $(dirname "$sample_dir"))
68- SAMPLE=$(basename "$sample_dir")
69- ZIP_NAME="${CATEGORY}-${SAMPLE}-sample"
70-
71- echo "🔨 Building: $ZIP_NAME"
72-
73- cd "$sample_dir"
74-
75- # Create comprehensive zip with security exclusions
76- zip -r "../../artifacts/${ZIP_NAME}.zip" . \
77- -x "*.git/*" \
78- -x "*/.git/*" \
79- -x "*node_modules/*" \
80- -x "*/__pycache__/*" \
81- -x "*.pyc" \
82- -x "*.pyo" \
83- -x "*dist/*" \
84- -x "*build/*" \
85- -x ".env" \
86- -x "*/.env" \
87- -x "*.env.local" \
88- -x "*.env.production" \
89- -x "*.env.development" \
90- -x "*venv/*" \
91- -x "*.venv/*" \
92- -x "*/.pytest_cache/*" \
93- -x "*/.coverage" \
94- -x "*/coverage/*" \
95- -x "*.log" \
96- -x "*/.DS_Store" \
97- -x "*/Thumbs.db" \
98- -x "*/.idea/*" \
99- -x "*/.vscode/*" \
100- -x "*/temp/*" \
101- -x "*/tmp/*" \
102- -x "*.tmp" \
103- -x "*/.cache/*" \
104- -x "*/.next/*" \
105- -x "*/target/*" \
106- -x "*/.gradle/*" \
107- -x "*/bin/*" \
108- -x "*/obj/*"
109-
128+ - name : Build quickstart packages from configs
129+ if : env.SHOULD_BUILD == 'true'
130+ run : |
131+ echo "📦 Building sample packages from configurations..."
132+
133+ find . -name "release-config.yml" -not -path "./.git/*" | while read config_file; do
134+ sample_dir=$(dirname "$config_file")
135+
136+ echo "🔨 Processing: $config_file"
137+ cd "$sample_dir"
138+
139+ # Check if this sample should be included
140+ INCLUDED=$(grep "^included:" release-config.yml | sed 's/included: *//' | tr -d ' ')
141+ if [ "$INCLUDED" != "true" ]; then
142+ echo "⏭️ Skipping (included: $INCLUDED)"
110143 cd - > /dev/null
111-
112- if [ -f "artifacts/${ZIP_NAME}.zip" ]; then
113- SIZE=$(du -h "artifacts/${ZIP_NAME}.zip" | cut -f1)
114- echo "✅ Created: ${ZIP_NAME}.zip ($SIZE)"
115- else
116- echo "❌ Failed to create: ${ZIP_NAME}.zip"
117- fi
144+ continue
145+ fi
146+
147+ # Extract configuration using basic shell parsing
148+ CATEGORY=$(grep "^category:" release-config.yml | sed 's/category: *"//' | sed 's/"$//' | tr -d ' ')
149+ FRAMEWORK=$(grep "^framework:" release-config.yml | sed 's/framework: *"//' | sed 's/"$//' | tr -d ' ')
150+
151+ if [ -z "$CATEGORY" ] || [ -z "$FRAMEWORK" ]; then
152+ echo "❌ Missing category or framework in $config_file"
153+ cd - > /dev/null
154+ continue
155+ fi
156+
157+ # Build zip filename from category and framework
158+ ZIP_FILENAME="${CATEGORY}-${FRAMEWORK}-sample"
159+
160+ echo "📦 Building: $ZIP_FILENAME.zip"
161+ echo "🏷️ Category: $CATEGORY, Framework: $FRAMEWORK"
162+
163+ # Start with default exclusions
164+ EXCLUDE_ARGS="-x .git/* -x node_modules/* -x __pycache__/* -x *.pyc -x *.pyo"
165+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x dist/* -x build/* -x venv/* -x .venv/*"
166+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x .pytest_cache/* -x .coverage -x coverage/*"
167+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x *.log -x .DS_Store -x Thumbs.db -x .idea/* -x .vscode/*"
168+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x temp/* -x tmp/* -x *.tmp -x .cache/* -x .next/*"
169+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x target/* -x .gradle/* -x bin/* -x obj/*"
170+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x .env -x .env.local -x .env.production -x .env.development"
171+
172+ # Add custom exclusions from config
173+ if grep -q "^exclude_patterns:" release-config.yml; then
174+ echo "📋 Adding custom exclusions from config"
175+ while IFS= read -r line; do
176+ if echo "$line" | grep -q "^ - "; then
177+ pattern=$(echo "$line" | sed 's/^ - "//' | sed 's/"$//' | tr -d ' ')
178+ if [ ! -z "$pattern" ]; then
179+ EXCLUDE_ARGS="$EXCLUDE_ARGS -x $pattern"
180+ echo " Excluding: $pattern"
181+ fi
182+ fi
183+ done < <(grep -A 20 "^exclude_patterns:" release-config.yml)
184+ fi
185+
186+ # Create the zip
187+ eval "zip -r \"../../artifacts/${ZIP_FILENAME}.zip\" . $EXCLUDE_ARGS"
188+
189+ cd - > /dev/null
190+
191+ if [ -f "artifacts/${ZIP_FILENAME}.zip" ]; then
192+ SIZE=$(du -h "artifacts/${ZIP_FILENAME}.zip" | cut -f1)
193+ echo "✅ Created: ${ZIP_FILENAME}.zip ($SIZE)"
194+ else
195+ echo "❌ Failed to create: ${ZIP_FILENAME}.zip"
118196 fi
119197 done
120198
@@ -128,6 +206,7 @@ jobs:
128206 ls -la artifacts/ || echo "No artifacts directory or files found"
129207
130208 - name : Security scan artifacts
209+ if : env.SHOULD_BUILD == 'true'
131210 run : |
132211 echo "🔍 Performing security checks on artifacts..."
133212
@@ -163,6 +242,7 @@ jobs:
163242 EOF
164243
165244 - name : Delete previous 'latest' release
245+ if : env.SHOULD_BUILD == 'true'
166246 env :
167247 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
168248 run : |
@@ -173,6 +253,7 @@ jobs:
173253 git push origin :refs/tags/latest 2>/dev/null || echo "No previous 'latest' tag found"
174254
175255 - name : Create test release (not latest)
256+ if : env.SHOULD_BUILD == 'true'
176257 env :
177258 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
178259 run : |
@@ -209,7 +290,8 @@ jobs:
209290 echo ""
210291 echo "🧪 This is a test release. Official releases coming soon"
211292
212- # - name: Create 'latest' release
293+ # - name: Create 'latest' release (for production)
294+ # if: env.SHOULD_BUILD == 'true'
213295 # env:
214296 # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
215297 # run: |
@@ -237,4 +319,10 @@ jobs:
237319 # FILENAME=$(basename "$zip_file")
238320 # echo " https://github.com/${{ github.repository }}/releases/latest/download/$FILENAME"
239321 # fi
240- # done
322+ # done
323+
324+ - name : Skip build notification
325+ if : env.SHOULD_BUILD == 'false'
326+ run : |
327+ echo "⏭️ Build skipped - no changes in directories with release-config.yml files"
328+ echo "💡 To force a rebuild, use the manual workflow trigger"
0 commit comments