name: Release Check on: # Allow manual trigger for testing workflow_dispatch: jobs: prepare: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} last_release: ${{ steps.last-release.outputs.hash }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Find package directories id: set-matrix run: | # Find all package.json and pyproject.toml files, excluding root DIRS=$(git ls-tree -r HEAD --name-only | grep -E "package.json|pyproject.toml" | xargs dirname | grep -v "^.$" | jq -R -s -c 'split("\n")[:-1]') echo "matrix=${DIRS}" >> $GITHUB_OUTPUT echo "Found directories: ${DIRS}" - name: Get last release hash id: last-release run: | HASH=$(git rev-list --tags --max-count=1 || echo "HEAD~1") echo "hash=${HASH}" >> $GITHUB_OUTPUT echo "Using last release hash: ${HASH}" check-release: needs: prepare runs-on: ubuntu-latest strategy: matrix: directory: ${{ fromJson(needs.prepare.outputs.matrix) }} fail-fast: false steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: astral-sh/setup-uv@v5 - name: Setup Node.js if: endsWith(matrix.directory, '/package.json') uses: actions/setup-node@v4 with: node-version: '18' - name: Setup Python if: endsWith(matrix.directory, '/pyproject.toml') run: uv python install - name: Check release id: check run: | # Create unique hash for this directory dir_hash=$(echo "${{ matrix.directory }}" | sha256sum | awk '{print $1}') # Run release check script with verbose output echo "Running release check against last release: ${{ needs.prepare.outputs.last_release }}" # Run git diff first to show changes echo "Changes since last release:" git diff --name-only "${{ needs.prepare.outputs.last_release }}" -- "${{ matrix.directory }}" || true # Run the release check output=$(uv run --script scripts/release.py --dry-run "${{ matrix.directory }}" "${{ needs.prepare.outputs.last_release }}" 2>&1) exit_code=$? echo "Release check output (exit code: $exit_code):" echo "$output" # Extract package info if successful if [ $exit_code -eq 0 ]; then pkg_info=$(echo "$output" | grep -o -E "[a-zA-Z0-9\-]+@[0-9]+\.[0-9]+\.[0-9]+" || true) else echo "Release check failed" exit 1 fi if [ ! -z "$pkg_info" ]; then echo "Found package that needs release: $pkg_info" # Create outputs directory mkdir -p ./outputs # Save both package info and full changes echo "$pkg_info" > "./outputs/${dir_hash}_info" echo "dir_hash=${dir_hash}" >> $GITHUB_OUTPUT # Log what we're saving echo "Saved package info to ./outputs/${dir_hash}_info:" cat "./outputs/${dir_hash}_info" else echo "No release needed for this package" fi - name: Set artifact name if: steps.check.outputs.dir_hash id: artifact run: | # Replace forward slashes with dashes SAFE_DIR=$(echo "${{ matrix.directory }}" | tr '/' '-') echo "name=release-outputs-${SAFE_DIR}" >> $GITHUB_OUTPUT - uses: actions/upload-artifact@v4 if: steps.check.outputs.dir_hash with: name: ${{ steps.artifact.outputs.name }} path: ./outputs/${{ steps.check.outputs.dir_hash }}* check-tag: needs: [prepare, check-release] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: pattern: release-outputs-src-* merge-multiple: true path: outputs - name: Simulate tag creation run: | if [ -d outputs ]; then # Collect package info find outputs -name "*_info" -exec cat {} \; > packages.txt if [ -s packages.txt ]; then DATE=$(date +%Y.%m.%d) echo "🔍 Dry run: Would create tag v${DATE} if this was a real release" # Generate comprehensive release notes { echo "# Release ${DATE}" echo "" echo "## Updated Packages" while IFS= read -r line; do echo "- $line" done < packages.txt } > notes.md echo "🔍 Would create release with following notes:" cat notes.md echo "🔍 Would create tag v${DATE} with the above release notes" echo "🔍 Would create GitHub release from tag v${DATE}" else echo "No packages need release" fi else echo "No release artifacts found" fi