Merge pull request #64 from Sambego/fix/next-updates #68
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release Sample Artifacts | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - '*/*/release-config.yml' | |
| - '*/**' | |
| - '!.github/**' | |
| - '!LICENSE' | |
| - '.github/workflows/create-sample-releases.yml' | |
| workflow_dispatch: | |
| inputs: | |
| force_rebuild: | |
| description: 'Force rebuild all artifacts' | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: write | |
| actions: read | |
| jobs: | |
| build-artifacts: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| - name: Create artifacts directory | |
| run: mkdir -p artifacts | |
| - name: Find and validate release configurations | |
| run: | | |
| echo "🔍 Finding release configurations..." | |
| RELEASE_CONFIGS=$(find . -name "release-config.yml" -not -path "./.git/*" | sort) | |
| if [ -z "$RELEASE_CONFIGS" ]; then | |
| echo "❌ No release-config.yml files found!" | |
| echo "📂 Available directories:" | |
| find . -type d -maxdepth 3 | head -20 | |
| exit 1 | |
| fi | |
| echo "✅ Found release configurations:" | |
| echo "$RELEASE_CONFIGS" | |
| # Validate each config file | |
| for config_file in $RELEASE_CONFIGS; do | |
| echo "📄 Validating: $config_file" | |
| # Check if it has required fields and included: true | |
| if grep -q "^category:" "$config_file" && grep -q "^framework:" "$config_file"; then | |
| INCLUDED=$(grep "^included:" "$config_file" | sed 's/included: *//' | tr -d ' ') | |
| if [ "$INCLUDED" = "true" ]; then | |
| echo " ✅ Valid configuration (included: true)" | |
| else | |
| echo " ⏭️ Skipping (included: $INCLUDED)" | |
| fi | |
| else | |
| echo " ❌ Missing required fields (category, framework) in $config_file" | |
| exit 1 | |
| fi | |
| done | |
| - name: Check if changed files are in configured directories | |
| run: | | |
| echo "🔍 Checking if changes affect configured quickstarts..." | |
| # Get list of directories with release-config.yml | |
| CONFIG_DIRS=$(find . -name "release-config.yml" -not -path "./.git/*" -exec dirname {} \; | sort) | |
| echo "📂 Directories with release-config.yml:" | |
| echo "$CONFIG_DIRS" | |
| # If this is a manual trigger, rebuild all | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "🔄 Manual trigger - will rebuild all configured samples" | |
| echo "SHOULD_BUILD=true" >> $GITHUB_ENV | |
| exit 0 | |
| fi | |
| # Check if any changed files are in directories with release-config.yml | |
| CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "") | |
| if [ -z "$CHANGED_FILES" ]; then | |
| echo "📝 No changed files detected, building all" | |
| echo "SHOULD_BUILD=true" >> $GITHUB_ENV | |
| exit 0 | |
| fi | |
| echo "📝 Changed files:" | |
| echo "$CHANGED_FILES" | |
| # Check if the workflow file itself was changed | |
| if echo "$CHANGED_FILES" | grep -q "^\.github/workflows/create-sample-releases\.yml$"; then | |
| echo "🔧 Workflow file changed - forcing rebuild of all samples" | |
| echo "SHOULD_BUILD=true" >> $GITHUB_ENV | |
| exit 0 | |
| fi | |
| SHOULD_BUILD=false | |
| for config_dir in $CONFIG_DIRS; do | |
| # Remove leading ./ | |
| clean_dir=$(echo "$config_dir" | sed 's|^\./||') | |
| # Check if any changed file is in this directory | |
| if echo "$CHANGED_FILES" | grep -q "^$clean_dir/"; then | |
| echo "✅ Changes detected in configured directory: $clean_dir" | |
| SHOULD_BUILD=true | |
| break | |
| fi | |
| done | |
| if [ "$SHOULD_BUILD" = "true" ]; then | |
| echo "🔄 Will rebuild artifacts (changes in configured directories)" | |
| echo "SHOULD_BUILD=true" >> $GITHUB_ENV | |
| else | |
| echo "⏭️ No changes in configured directories, skipping build" | |
| echo "SHOULD_BUILD=false" >> $GITHUB_ENV | |
| fi | |
| - name: Download existing release assets (if any) | |
| if: env.SHOULD_BUILD == 'true' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "📥 Checking for existing 'latest' release assets..." | |
| # Get changed files | |
| CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "") | |
| # Determine if we should preserve existing assets | |
| PRESERVE_ASSETS=true | |
| if echo "$CHANGED_FILES" | grep -q "^\.github/workflows/create-sample-releases\.yml$"; then | |
| echo "🔧 Workflow file changed - skipping asset preservation (full rebuild)" | |
| PRESERVE_ASSETS=false | |
| elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ github.event.inputs.force_rebuild }}" = "true" ]; then | |
| echo "🔄 Force rebuild requested - skipping asset preservation (full rebuild)" | |
| PRESERVE_ASSETS=false | |
| elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "🔄 Manual trigger - skipping asset preservation (full rebuild)" | |
| PRESERVE_ASSETS=false | |
| fi | |
| if [ "$PRESERVE_ASSETS" = "true" ]; then | |
| # Check if latest release exists | |
| if gh release view latest >/dev/null 2>&1; then | |
| echo "✅ Found existing 'latest' release" | |
| # Download existing assets to preserve them | |
| mkdir -p existing_assets | |
| gh release download latest --dir existing_assets 2>/dev/null || echo "No assets to download" | |
| # Move existing assets to artifacts directory | |
| for existing_zip in existing_assets/*.zip; do | |
| if [ -f "$existing_zip" ]; then | |
| FILENAME=$(basename "$existing_zip") | |
| echo "📦 Preserving existing: $FILENAME" | |
| cp "$existing_zip" "artifacts/" | |
| fi | |
| done | |
| rm -rf existing_assets | |
| else | |
| echo "ℹ️ No existing 'latest' release found" | |
| fi | |
| else | |
| echo "🧹 Skipping asset preservation - will rebuild all from scratch" | |
| fi | |
| - name: Build quickstart packages from configs | |
| if: env.SHOULD_BUILD == 'true' | |
| run: | | |
| echo "📦 Building sample packages from configurations..." | |
| # Store the absolute path to artifacts directory | |
| ARTIFACTS_DIR="$(pwd)/artifacts" | |
| # Get changed files to determine which directories to rebuild | |
| CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "") | |
| # Check if workflow file changed (rebuild all if so) | |
| REBUILD_ALL=false | |
| if echo "$CHANGED_FILES" | grep -q "^\.github/workflows/create-sample-releases\.yml$"; then | |
| echo "🔧 Workflow file changed - rebuilding ALL samples" | |
| REBUILD_ALL=true | |
| elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "🔄 Manual trigger - rebuilding ALL samples" | |
| REBUILD_ALL=true | |
| elif [ "${{ github.event.inputs.force_rebuild }}" = "true" ]; then | |
| echo "🔄 Force rebuild requested - rebuilding ALL samples" | |
| REBUILD_ALL=true | |
| elif [ -z "$CHANGED_FILES" ]; then | |
| echo "📝 No changed files detected - rebuilding ALL samples" | |
| REBUILD_ALL=true | |
| fi | |
| find . -name "release-config.yml" -not -path "./.git/*" | while read config_file; do | |
| sample_dir=$(dirname "$config_file") | |
| clean_dir=$(echo "$sample_dir" | sed 's|^\./||') | |
| # Check if this specific directory should be rebuilt | |
| SHOULD_REBUILD=false | |
| if [ "$REBUILD_ALL" = "true" ]; then | |
| SHOULD_REBUILD=true | |
| echo "🔨 Processing: $config_file (rebuild all)" | |
| elif echo "$CHANGED_FILES" | grep -q "^$clean_dir/"; then | |
| SHOULD_REBUILD=true | |
| echo "🔨 Processing: $config_file (changes detected in $clean_dir)" | |
| else | |
| echo "⏭️ Skipping: $config_file (no changes in $clean_dir)" | |
| continue | |
| fi | |
| # Only process if this directory should be rebuilt | |
| if [ "$SHOULD_REBUILD" = "true" ]; then | |
| cd "$sample_dir" | |
| # Check if this sample should be included | |
| INCLUDED=$(grep "^included:" release-config.yml | sed 's/included: *//' | tr -d ' ') | |
| if [ "$INCLUDED" != "true" ]; then | |
| echo "⏭️ Skipping (included: $INCLUDED)" | |
| cd - > /dev/null | |
| continue | |
| fi | |
| # Extract configuration using basic shell parsing | |
| CATEGORY=$(grep "^category:" release-config.yml | sed 's/category: *"//' | sed 's/"$//' | tr -d ' ') | |
| FRAMEWORK=$(grep "^framework:" release-config.yml | sed 's/framework: *"//' | sed 's/"$//' | tr -d ' ') | |
| if [ -z "$CATEGORY" ] || [ -z "$FRAMEWORK" ]; then | |
| echo "❌ Missing category or framework in $config_file" | |
| cd - > /dev/null | |
| continue | |
| fi | |
| # Build zip filename from category and framework | |
| ZIP_FILENAME="${CATEGORY}-${FRAMEWORK}-sample" | |
| echo "📦 Building: $ZIP_FILENAME.zip" | |
| echo "🏷️ Category: $CATEGORY, Framework: $FRAMEWORK" | |
| echo "📁 Current directory: $(pwd)" | |
| echo "📁 Artifacts directory: $ARTIFACTS_DIR" | |
| # Create zip with absolute path to artifacts directory (this will overwrite existing) | |
| zip -r "${ARTIFACTS_DIR}/${ZIP_FILENAME}.zip" . \ | |
| --exclude=".git/*" \ | |
| --exclude="node_modules/*" \ | |
| --exclude="__pycache__/*" \ | |
| --exclude="*.pyc" \ | |
| --exclude="*.pyo" \ | |
| --exclude="dist/*" \ | |
| --exclude="build/*" \ | |
| --exclude="venv/*" \ | |
| --exclude=".venv/*" \ | |
| --exclude=".pytest_cache/*" \ | |
| --exclude=".coverage" \ | |
| --exclude="coverage/*" \ | |
| --exclude="*.log" \ | |
| --exclude=".DS_Store" \ | |
| --exclude="Thumbs.db" \ | |
| --exclude=".idea/*" \ | |
| --exclude=".vscode/*" \ | |
| --exclude="temp/*" \ | |
| --exclude="tmp/*" \ | |
| --exclude="*.tmp" \ | |
| --exclude=".cache/*" \ | |
| --exclude=".next/*" \ | |
| --exclude="target/*" \ | |
| --exclude=".gradle/*" \ | |
| --exclude="bin/*" \ | |
| --exclude="obj/*" \ | |
| --exclude=".env" \ | |
| --exclude=".env.local" \ | |
| --exclude=".env.production" \ | |
| --exclude=".env.development" \ | |
| --exclude="release-config.yml" | |
| # Add custom exclusions from config if they exist | |
| if grep -q "^exclude_patterns:" release-config.yml; then | |
| echo "📋 Adding custom exclusions from config..." | |
| # Create a temporary zip with custom exclusions | |
| TEMP_ZIP="${ARTIFACTS_DIR}/temp_${ZIP_FILENAME}.zip" | |
| mv "${ARTIFACTS_DIR}/${ZIP_FILENAME}.zip" "$TEMP_ZIP" | |
| # Extract and re-zip with custom exclusions | |
| mkdir -p temp_extract | |
| cd temp_extract | |
| unzip -q "$TEMP_ZIP" | |
| # Apply custom exclusions | |
| while IFS= read -r line; do | |
| if echo "$line" | grep -q "^ - "; then | |
| pattern=$(echo "$line" | sed 's/^ - "//' | sed 's/"$//' | tr -d ' ') | |
| if [ ! -z "$pattern" ]; then | |
| echo " Excluding custom pattern: $pattern" | |
| find . -name "$pattern" -delete 2>/dev/null || true | |
| fi | |
| fi | |
| done < <(grep -A 20 "^exclude_patterns:" ../release-config.yml) | |
| # Re-create zip with absolute path | |
| zip -r "${ARTIFACTS_DIR}/${ZIP_FILENAME}.zip" . | |
| cd .. | |
| rm -rf temp_extract "$TEMP_ZIP" | |
| fi | |
| cd - > /dev/null | |
| if [ -f "${ARTIFACTS_DIR}/${ZIP_FILENAME}.zip" ]; then | |
| SIZE=$(du -h "${ARTIFACTS_DIR}/${ZIP_FILENAME}.zip" | cut -f1) | |
| echo "✅ Created/Updated: ${ZIP_FILENAME}.zip ($SIZE)" | |
| else | |
| echo "❌ Failed to create: ${ZIP_FILENAME}.zip" | |
| fi | |
| fi | |
| done | |
| # Count artifacts AFTER the loop completes | |
| ARTIFACT_COUNT=$(ls artifacts/*.zip 2>/dev/null | wc -l) | |
| echo "ARTIFACT_COUNT=$ARTIFACT_COUNT" >> $GITHUB_ENV | |
| echo "📊 Total artifacts for release: $ARTIFACT_COUNT" | |
| # Debug: List what will be included in the release | |
| echo "📦 Artifacts for release:" | |
| ls -la artifacts/ || echo "No artifacts directory or files found" | |
| - name: Security scan artifacts | |
| if: env.SHOULD_BUILD == 'true' | |
| run: | | |
| echo "🔍 Performing security checks on artifacts..." | |
| for zip_file in artifacts/*.zip; do | |
| if [ -f "$zip_file" ]; then | |
| echo "Scanning: $(basename "$zip_file")" | |
| # Check for actual sensitive files (not config examples) | |
| SENSITIVE_FILES=$(unzip -l "$zip_file" 2>/dev/null | grep -E "\.(key|pem|p12|pfx)$|/\.env$|\.env\.(local|production|development)$|secret\." | grep -v -E "\.(example|sample|template)" || true) | |
| if [ ! -z "$SENSITIVE_FILES" ]; then | |
| echo "⚠️ Warning: Potential sensitive files in $(basename "$zip_file"):" | |
| echo "$SENSITIVE_FILES" | |
| else | |
| echo "✅ No sensitive files detected" | |
| fi | |
| fi | |
| done | |
| - name: Generate release notes | |
| if: env.SHOULD_BUILD == 'true' | |
| run: | | |
| echo "📝 Generating release notes..." | |
| cat > release_notes.md << EOF | |
| # Quickstart Samples | |
| This release contains the latest version of sample applications for various frameworks and quickstarts. See Assets below for downloadable zip files of each quickstart. | |
| For more information, visit [auth0.com/ai/docs](https://auth0.com/ai/docs). | |
| --- | |
| **Generated:** $(date -u '+%Y-%m-%d %H:%M:%S UTC') | |
| EOF | |
| - name: Delete previous 'latest' release | |
| if: env.SHOULD_BUILD == 'true' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "🗑️ Cleaning up previous 'latest' release..." | |
| # Delete previous latest release (ignore errors if doesn't exist) | |
| gh release delete latest --yes 2>/dev/null || echo "No previous 'latest' release found" | |
| git push origin :refs/tags/latest 2>/dev/null || echo "No previous 'latest' tag found" | |
| # Also clean up local tag | |
| git tag -d latest 2>/dev/null || echo "No local 'latest' tag found" | |
| - name: Create 'latest' release | |
| if: env.SHOULD_BUILD == 'true' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "🚀 Creating 'latest' release..." | |
| if [ "$ARTIFACT_COUNT" -eq 0 ]; then | |
| echo "❌ No artifacts to release!" | |
| exit 1 | |
| fi | |
| echo "📦 Releasing $ARTIFACT_COUNT artifacts" | |
| # Create the latest release | |
| gh release create latest \ | |
| --title "Auth0 AI Sample Artifacts - Latest" \ | |
| --notes-file release_notes.md \ | |
| --latest \ | |
| artifacts/*.zip | |
| echo "✅ Latest release created!" | |
| echo "🔗 Your download URLs are now active:" | |
| for zip_file in artifacts/*.zip; do | |
| if [ -f "$zip_file" ]; then | |
| FILENAME=$(basename "$zip_file") | |
| echo " https://github.com/${{ github.repository }}/releases/latest/download/$FILENAME" | |
| fi | |
| done | |
| - name: Skip build notification | |
| if: env.SHOULD_BUILD == 'false' | |
| run: | | |
| echo "⏭️ Build skipped - no changes in directories with release-config.yml files" | |
| echo "💡 To force a rebuild, use the manual workflow trigger" |