Merge pull request #25 from LittleCoinCoin/schema-updates #19
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: Schema Deployment | |
| # This workflow handles the deployment of schemas via GitHub Releases. | |
| # Schemas are validated and then published as GitHub releases with direct file attachments. | |
| # This provides multiple access patterns: | |
| # - Direct raw file access via raw.githubusercontent.com URLs | |
| # - Release-based downloads with metadata | |
| # - GitHub API access for programmatic discovery | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'package/v*/**' | |
| - 'registry/v*/**' | |
| - '.github/workflows/schema-deployment.yml' | |
| workflow_dispatch: # Allows manual triggering of the workflow | |
| inputs: | |
| force: | |
| description: 'Force deployment even if no changes detected' | |
| type: boolean | |
| required: true | |
| default: false | |
| pkg_schema_version: | |
| description: 'Package schema version' | |
| type: string | |
| required: false | |
| default: 'v1' | |
| registry_schema_version: | |
| description: 'Registry schema version' | |
| type: string | |
| required: false | |
| default: 'v1' | |
| permissions: | |
| contents: write # For GitHub Releases | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| pkg_versions: ${{ steps.extract-versions.outputs.pkg_versions }} | |
| registry_versions: ${{ steps.extract-versions.outputs.registry_versions }} | |
| highest_pkg_version: ${{ steps.extract-versions.outputs.highest_pkg_version }} | |
| highest_registry_version: ${{ steps.extract-versions.outputs.highest_registry_version }} | |
| has_changes: ${{ steps.extract-versions.outputs.has_changes }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get changed files | |
| id: changed-files | |
| uses: tj-actions/changed-files@v46 | |
| with: | |
| files: | | |
| package/v*/** | |
| registry/v*/** | |
| - name: Extract versions from changed files | |
| id: extract-versions | |
| run: | | |
| # Handle workflow_dispatch with force | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.force }}" == "true" ]]; then | |
| echo "pkg_versions=[\"${{ github.event.inputs.pkg_schema_version }}\"]" >> $GITHUB_OUTPUT | |
| echo "registry_versions=[\"${{ github.event.inputs.registry_schema_version }}\"]" >> $GITHUB_OUTPUT | |
| echo "highest_pkg_version=${{ github.event.inputs.pkg_schema_version }}" >> $GITHUB_OUTPUT | |
| echo "highest_registry_version=${{ github.event.inputs.registry_schema_version }}" >> $GITHUB_OUTPUT | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Use tj-actions/changed-files with matrix to get versions | |
| changed_files="${{ steps.changed-files.outputs.all_changed_files }}" | |
| # Extract unique versions using simple regex | |
| pkg_versions=$(echo "$changed_files" | grep -oE 'package/v[0-9]+(\.[0-9]+)*' | cut -d'/' -f2 | sort -u | jq -R -c . | jq -s -c .) | |
| registry_versions=$(echo "$changed_files" | grep -oE 'registry/v[0-9]+(\.[0-9]+)*' | cut -d'/' -f2 | sort -u | jq -R -c . | jq -s -c .) | |
| # Handle empty arrays | |
| if [[ "$pkg_versions" == "[null]" ]] || [[ -z "$pkg_versions" ]]; then pkg_versions="[]"; fi | |
| if [[ "$registry_versions" == "[null]" ]] || [[ -z "$registry_versions" ]]; then registry_versions="[]"; fi | |
| # Find highest versions | |
| highest_pkg=$(echo "$pkg_versions" | jq -r '.[]' | sort -V | tail -n1) | |
| highest_registry=$(echo "$registry_versions" | jq -r '.[]' | sort -V | tail -n1) | |
| # Set outputs | |
| echo "pkg_versions=$pkg_versions" >> $GITHUB_OUTPUT | |
| echo "registry_versions=$registry_versions" >> $GITHUB_OUTPUT | |
| echo "highest_pkg_version=$highest_pkg" >> $GITHUB_OUTPUT | |
| echo "highest_registry_version=$highest_registry" >> $GITHUB_OUTPUT | |
| # Check if we have changes | |
| if [[ "$pkg_versions" != "[]" ]] || [[ "$registry_versions" != "[]" ]]; then | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| fi | |
| validate-schemas: | |
| if: needs.detect-changes.outputs.has_changes == 'true' | |
| needs: [detect-changes] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| schema-type: [package, registry] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js for schema validation | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| - name: Install AJV for validation | |
| run: npm install -g ajv-cli ajv-formats | |
| - name: Validate schemas | |
| run: | | |
| schema_type="${{ matrix.schema-type }}" | |
| if [[ "$schema_type" == "package" ]]; then | |
| versions='${{ needs.detect-changes.outputs.pkg_versions }}' | |
| file_name="hatch_pkg_metadata_schema.json" | |
| else | |
| versions='${{ needs.detect-changes.outputs.registry_versions }}' | |
| file_name="hatch_all_pkg_metadata_schema.json" | |
| fi | |
| if [[ "$versions" == "[]" ]]; then | |
| echo "No $schema_type schema changes detected, skipping validation" | |
| exit 0 | |
| fi | |
| echo "Validating $schema_type schemas for versions: $versions" | |
| for version in $(echo "$versions" | jq -r '.[]'); do | |
| schema_file="$schema_type/$version/$file_name" | |
| if [[ -f "$schema_file" ]]; then | |
| echo "Validating: $schema_file" | |
| ajv compile -s "$schema_file" --spec=draft7 -c ajv-formats | |
| else | |
| echo "Error: Schema file not found at $schema_file" | |
| exit 1 | |
| fi | |
| done | |
| deploy-releases: | |
| if: needs.detect-changes.outputs.has_changes == 'true' | |
| needs: [detect-changes, validate-schemas] | |
| runs-on: ubuntu-latest | |
| env: | |
| PKG_VERSIONS: ${{ needs.detect-changes.outputs.pkg_versions }} | |
| REGISTRY_VERSIONS: ${{ needs.detect-changes.outputs.registry_versions }} | |
| HIGHEST_PKG_VERSION: ${{ needs.detect-changes.outputs.highest_pkg_version }} | |
| HIGHEST_REGISTRY_VERSION: ${{ needs.detect-changes.outputs.highest_registry_version }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Display deployment information | |
| if: needs.detect-changes.outputs.pkg_versions != '[]' | |
| uses: softprops/action-gh-release@v2.2.2 | |
| with: | |
| tag_name: schemas-package-${{ needs.detect-changes.outputs.highest_pkg_version }} | |
| name: Package Schema Release ${{ needs.detect-changes.outputs.highest_pkg_version }} | |
| body: | | |
| Package schema version ${{ needs.detect-changes.outputs.highest_pkg_version }} released on ${{ github.event.head_commit.timestamp }} | |
| **Changed Versions:** ${{ needs.detect-changes.outputs.pkg_versions }} | |
| **Commit:** ${{ github.sha }} | |
| files: | | |
| package/${{ needs.detect-changes.outputs.highest_pkg_version }}/* | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create registry schema releases | |
| if: needs.detect-changes.outputs.registry_versions != '[]' | |
| uses: softprops/action-gh-release@v2.2.2 | |
| with: | |
| tag_name: schemas-registry-${{ needs.detect-changes.outputs.highest_registry_version }} | |
| name: Registry Schema Release ${{ needs.detect-changes.outputs.highest_registry_version }} | |
| body: | | |
| Registry schema version ${{ needs.detect-changes.outputs.highest_registry_version }} released on ${{ github.event.head_commit.timestamp }} | |
| **Changed Versions:** ${{ needs.detect-changes.outputs.registry_versions }} | |
| **Commit:** ${{ github.sha }} | |
| files: | | |
| registry/${{ needs.detect-changes.outputs.highest_registry_version }}/* | |
| fail_on_unmatched_files: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate deployment summary | |
| run: | | |
| echo "## Schema Deployment Complete! 🎉" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [[ "$PKG_VERSIONS" != "[]" ]]; then | |
| echo "### Package Schema Releases" >> $GITHUB_STEP_SUMMARY | |
| pkg_versions='${{ needs.detect-changes.outputs.pkg_versions }}' | |
| for version in $(echo "$pkg_versions" | jq -r '.[]'); do | |
| echo "- **$version**: [Release](https://github.com/${{ github.repository }}/releases/tag/schemas-package-$version) | [Raw Schema](https://raw.githubusercontent.com/${{ github.repository }}/main/package/$version/hatch_pkg_metadata_schema.json)" >> $GITHUB_STEP_SUMMARY | |
| done | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [[ "$REGISTRY_VERSIONS" != "[]" ]]; then | |
| echo "### Registry Schema Releases" >> $GITHUB_STEP_SUMMARY | |
| registry_versions='${{ needs.detect-changes.outputs.registry_versions }}' | |
| for version in $(echo "$registry_versions" | jq -r '.[]'); do | |
| echo "- **$version**: [Release](https://github.com/${{ github.repository }}/releases/tag/schemas-registry-$version) | [Raw Schema](https://raw.githubusercontent.com/${{ github.repository }}/main/registry/$version/hatch_all_pkg_metadata_schema.json)" >> $GITHUB_STEP_SUMMARY | |
| done | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "### Latest Versions" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Package**: $HIGHEST_PKG_VERSION" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Registry**: $HIGHEST_REGISTRY_VERSION" >> $GITHUB_STEP_SUMMARY |