diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 588cacf5..b39a543d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,31 +1,18 @@ -name: Release +name: Automatic Release Creation on: - schedule: - # Run every day at 9:00 UTC - - cron: '0 9 * * *' - # Allow manual trigger for testing workflow_dispatch: jobs: - prepare: + detect-last-release: 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: | @@ -33,97 +20,62 @@ jobs: echo "hash=${HASH}" >> $GITHUB_OUTPUT echo "Using last release hash: ${HASH}" - release: - needs: prepare + create-tag-name: runs-on: ubuntu-latest - environment: release - strategy: - matrix: - directory: ${{ fromJson(needs.prepare.outputs.matrix) }} - fail-fast: false - permissions: - contents: write - packages: write + outputs: + tag_name: ${{ steps.last-release.outputs.tag}} + steps: + - name: Get last release hash + id: last-release + run: | + DATE=$(date +%Y.%m.%d) + echo "tag=v${DATE}" >> $GITHUB_OUTPUT + echo "Using tag: v${DATE}" + detect-packages: + runs-on: ubuntu-latest + outputs: + packages: ${{ steps.find-packages.outputs.packages }} steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: astral-sh/setup-uv@v5 + - name: Find packages + id: find-packages + working-directory: src + run: | + # Find all package.json and pyproject.toml files + PACKAGES=$(find . \( -name "package.json" -o -name "pyproject.toml" \) -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]') + echo "packages=$PACKAGES" >> $GITHUB_OUTPUT - - name: Setup Node.js - if: endsWith(matrix.directory, '/package.json') - uses: actions/setup-node@v4 + detect-updates: + needs: [detect-packages, detect-last-release] + strategy: + matrix: + package: ${{ fromJson(needs.detect-packages.outputs.packages) }} + name: Check ${{ matrix.package }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 with: - node-version: '18' - registry-url: 'https://registry.npmjs.org' - - - name: Setup Python - if: endsWith(matrix.directory, '/pyproject.toml') - run: uv python install + fetch-depth: 0 - - name: Release package - id: release - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }} + - name: Check updates + working-directory: src/${{ matrix.package }} run: | - # Create unique hash for this directory - dir_hash=$(echo "${{ matrix.directory }}" | sha256sum | awk '{print $1}') - - # 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 - output=$(uv run --script scripts/release.py "${{ matrix.directory }}" "${{ needs.prepare.outputs.last_release }}" 2>&1) - exit_code=$? - - echo "Release 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 failed" - exit 1 - fi - - if [ ! -z "$pkg_info" ]; then - echo "Released package: $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" + mkdir -p '.info/${{ matrix.package }}' + if git diff --name-only ${{ needs.detect-last-release.outputs.last_release }}..HEAD -- "*.py" "*.ts" ; then + echo "Changes detected in Python or TypeScript files for ${{ matrix.package }}" + echo "${{ matrix.package }}" > ".info/${{ matrix.package }}/changed" fi - - name: Set artifact name - if: steps.release.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.release.outputs.dir_hash + - name: Upload artifacts + uses: actions/upload-artifact@v4 with: - name: ${{ steps.artifact.outputs.name }} - path: ./outputs/${{ steps.release.outputs.dir_hash }}* + name: release-${{ matrix.package }} + path: .info/${{ matrix.package }} create-tag: - needs: [prepare, release] + needs: [detect-updates, create-tag-name] runs-on: ubuntu-latest permissions: contents: write @@ -132,25 +84,26 @@ jobs: - uses: actions/download-artifact@v4 with: - pattern: release-outputs-src-* + pattern: release-* merge-multiple: true path: outputs - - name: Create tag and release + - name: Create release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if [ -d outputs ]; then + # Configure git + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + # Collect package info - find outputs -name "*_info" -exec cat {} \; > packages.txt + find outputs -name "changed" -exec cat {} \; > packages.txt if [ -s packages.txt ]; then - DATE=$(date +%Y.%m.%d) - echo "Creating tag v${DATE}" - # Generate comprehensive release notes { - echo "# Release ${DATE}" + echo "# Release ${{ needs.create-tag-name.outputs.tag_name }}" echo "" echo "## Updated Packages" while IFS= read -r line; do @@ -159,16 +112,16 @@ jobs: } > notes.md # Create and push tag - git tag -a "v${DATE}" -m "Release ${DATE}" - git push origin "v${DATE}" + git tag -a "${{ needs.create-tag-name.outputs.tag_name }}" -m "Release ${{ needs.create-tag-name.outputs.tag_name }}" + git push origin "${{ needs.create-tag-name.outputs.tag_name }}" # Create GitHub release - gh release create "v${DATE}" \ - --title "Release ${DATE}" \ + gh release create "${{ needs.create-tag-name.outputs.tag_name }}" \ + --title "Release ${{ needs.create-tag-name.outputs.tag_name }}" \ --notes-file notes.md else echo "No packages need release" fi else echo "No release artifacts found" - fi \ No newline at end of file + fi