Add orderingKey support for message queues #256
Workflow file for this run
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
| # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json | |
| # | |
| # Main CI workflow for testing, linting, and publishing to JSR/npm. | |
| # npm publishing is handled by build.yaml, which is triggered via workflow_dispatch | |
| # from the publish-npm job. This allows npm publishing to run in parallel with | |
| # docs publishing, rather than waiting for the entire workflow to complete. | |
| # See build.yaml for details on why this separation is required for npm's | |
| # trusted publishing (OIDC). | |
| name: main | |
| on: [push, pull_request] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| issues: read | |
| checks: write | |
| pull-requests: write | |
| services: | |
| rabbitmq: | |
| image: rabbitmq | |
| env: | |
| RABBITMQ_DEFAULT_USER: guest | |
| RABBITMQ_DEFAULT_PASS: guest | |
| ports: | |
| - 5672:5672 | |
| options: >- | |
| --health-cmd "rabbitmq-diagnostics -q ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| postgres: | |
| image: postgres | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| redis: | |
| image: redis | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| env: | |
| AMQP_URL: amqp://guest:guest@localhost:5672 | |
| POSTGRES_URL: postgres://postgres:postgres@localhost:5432/postgres | |
| REDIS_URL: redis://localhost:6379 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - name: Enable RabbitMQ consistent hash exchange plugin | |
| run: docker exec ${{ job.services.rabbitmq.id }} rabbitmq-plugins enable rabbitmq_consistent_hash_exchange | |
| - run: mise run test:deno -- --coverage=.cov --junit-path=.test-report.xml | |
| env: | |
| RUST_BACKTRACE: ${{ runner.debug }} | |
| LOG: ${{ runner.debug && 'always' || '' }} | |
| AMQP_ORDERING_TEST: "true" | |
| - uses: dorny/test-reporter@v2 | |
| if: success() || failure() | |
| with: | |
| name: "Test Results (${{ matrix.os }})" | |
| path: .test-report.xml | |
| reporter: jest-junit | |
| continue-on-error: true | |
| - if: '!cancelled()' | |
| uses: codecov/test-results-action@v1 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: .test-report.xml | |
| - run: deno coverage --lcov .cov > .cov.lcov | |
| continue-on-error: true | |
| - uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: .cov.lcov | |
| continue-on-error: true | |
| test-node: | |
| runs-on: ubuntu-latest | |
| services: | |
| rabbitmq: | |
| image: rabbitmq | |
| env: | |
| RABBITMQ_DEFAULT_USER: guest | |
| RABBITMQ_DEFAULT_PASS: guest | |
| ports: | |
| - 5672:5672 | |
| options: >- | |
| --health-cmd "rabbitmq-diagnostics -q ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| postgres: | |
| image: postgres | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| redis: | |
| image: redis | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| env: | |
| AMQP_URL: amqp://guest:guest@localhost:5672 | |
| POSTGRES_URL: postgres://postgres:postgres@localhost:5432/postgres | |
| REDIS_URL: redis://localhost:6379 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - name: Enable RabbitMQ consistent hash exchange plugin | |
| run: docker exec ${{ job.services.rabbitmq.id }} rabbitmq-plugins enable rabbitmq_consistent_hash_exchange | |
| - run: mise run test:node | |
| env: | |
| AMQP_ORDERING_TEST: "true" | |
| test-bun: | |
| runs-on: ubuntu-latest | |
| services: | |
| rabbitmq: | |
| image: rabbitmq | |
| env: | |
| RABBITMQ_DEFAULT_USER: guest | |
| RABBITMQ_DEFAULT_PASS: guest | |
| ports: | |
| - 5672:5672 | |
| options: >- | |
| --health-cmd "rabbitmq-diagnostics -q ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| postgres: | |
| image: postgres | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: postgres | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| redis: | |
| image: redis | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| env: | |
| AMQP_URL: amqp://guest:guest@localhost:5672 | |
| POSTGRES_URL: postgres://postgres:postgres@localhost:5432/postgres | |
| REDIS_URL: redis://localhost:6379 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - name: Enable RabbitMQ consistent hash exchange plugin | |
| run: docker exec ${{ job.services.rabbitmq.id }} rabbitmq-plugins enable rabbitmq_consistent_hash_exchange | |
| - run: mise run test:bun | |
| env: | |
| AMQP_ORDERING_TEST: "true" | |
| test-cfworkers: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: deno task test:cfworkers | |
| working-directory: ${{ github.workspace }}/packages/fedify/ | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: mise run check | |
| release-test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: '[[ "$(jq -r .version deno.json)" = "$(jq -r .version package.json)" ]]' | |
| working-directory: ${{ github.workspace }}/packages/fedify/ | |
| - run: mise run codegen | |
| - run: deno publish --dry-run | |
| - run: pnpm publish --recursive --dry-run --no-git-checks | |
| # =========================================================================== | |
| # PR-only jobs: Validate CLI and docs build | |
| # =========================================================================== | |
| build-cli-pr: | |
| if: github.event_name == 'pull_request' | |
| needs: [release-test] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: mise run codegen | |
| - run: deno task pack | |
| working-directory: ${{ github.workspace }}/packages/cli/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: cli-pr-${{ github.event.pull_request.number }} | |
| path: | | |
| packages/cli/fedify-cli-*.tar.xz | |
| packages/cli/fedify-cli-*.zip | |
| build-docs-pr: | |
| if: github.event_name == 'pull_request' | |
| needs: [release-test] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: pnpm run build | |
| working-directory: ${{ github.workspace }}/docs/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: docs-pr-${{ github.event.pull_request.number }} | |
| path: docs/.vitepress/dist | |
| # =========================================================================== | |
| # Push-only jobs: Determine version | |
| # =========================================================================== | |
| determine-version: | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| short_version: ${{ steps.version.outputs.short_version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - id: version | |
| uses: ./.github/actions/determine-version | |
| - if: github.ref_type == 'tag' | |
| run: | | |
| set -ex | |
| [[ "$(jq -r .version deno.json)" = "$GITHUB_REF_NAME" ]] | |
| ! grep -i "to be released" CHANGES.md | |
| working-directory: ${{ github.workspace }}/packages/fedify/ | |
| # =========================================================================== | |
| # Push-only jobs: Build artifacts (run in parallel after version determined) | |
| # =========================================================================== | |
| build-cli: | |
| if: github.event_name == 'push' | |
| needs: [test, test-node, test-bun, test-cfworkers, lint, release-test, determine-version] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - uses: ./.github/actions/determine-version | |
| - run: mise run codegen | |
| - run: deno task pack | |
| working-directory: ${{ github.workspace }}/packages/cli/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: cli | |
| path: | | |
| packages/cli/fedify-cli-*.tar.xz | |
| packages/cli/fedify-cli-*.zip | |
| build-packages: | |
| if: github.event_name == 'push' | |
| needs: [test, test-node, test-bun, test-cfworkers, lint, release-test, determine-version] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - uses: ./.github/actions/determine-version | |
| - run: sudo npm install -g npm@latest && npm --version | |
| - run: | | |
| pnpm pack --recursive --filter='!./examples/**' | |
| # Remove private packages | |
| for pkg in fedify-*.tgz; do | |
| if tar -xOzf "$pkg" package/package.json | jq -e '.private == true' > /dev/null 2>&1; then | |
| echo "Removing private package: $pkg" | |
| rm "$pkg" | |
| fi | |
| done | |
| if [[ "$GITHUB_REF_TYPE" != tag ]]; then | |
| rm fedify-cli-*.tgz | |
| fi | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: npm-packages | |
| path: fedify-*.tgz | |
| publish-jsr: | |
| if: github.event_name == 'push' | |
| needs: [test, test-node, test-bun, test-cfworkers, lint, release-test, determine-version] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - uses: ./.github/actions/determine-version | |
| - run: | | |
| set -ex | |
| mise run codegen | |
| max_attempts=5 | |
| attempt=1 | |
| until deno publish --allow-dirty; do | |
| exit_code=$? | |
| if [[ $attempt -ge $max_attempts ]]; then | |
| echo "deno publish failed after $max_attempts attempts" | |
| exit $exit_code | |
| fi | |
| echo "deno publish failed (attempt $attempt/$max_attempts), retrying in 30 seconds..." | |
| sleep 30 | |
| ((attempt++)) | |
| done | |
| # =========================================================================== | |
| # Push-only jobs: Create GitHub release (tag only) | |
| # =========================================================================== | |
| create-release: | |
| if: github.event_name == 'push' && github.ref_type == 'tag' | |
| needs: [build-cli, build-packages, publish-jsr] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: cli | |
| path: cli-artifacts/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: npm-packages | |
| path: npm-artifacts/ | |
| - id: extract-changelog | |
| uses: dahlia/submark@5a5ff0a58382fb812616a5801402f5aef00f90ce | |
| with: | |
| input-file: CHANGES.md | |
| heading-level: 2 | |
| heading-title-text: version ${{ github.ref_name }} | |
| ignore-case: true | |
| omit-heading: true | |
| - run: 'cat "$CHANGES_FILE"' | |
| env: | |
| CHANGES_FILE: ${{ steps.extract-changelog.outputs.output-file }} | |
| - uses: softprops/action-gh-release@v1 | |
| with: | |
| body_path: ${{ steps.extract-changelog.outputs.output-file }} | |
| name: Fedify ${{ github.ref_name }} | |
| files: | | |
| npm-artifacts/fedify-*.tgz | |
| cli-artifacts/fedify-cli-*.tar.xz | |
| cli-artifacts/fedify-cli-*.zip | |
| generate_release_notes: false | |
| # =========================================================================== | |
| # Push-only jobs: Publish to npm and docs | |
| # =========================================================================== | |
| # Trigger build.yaml via workflow_dispatch to publish to npm. | |
| # This is required because npm's trusted publishing (OIDC) validates | |
| # the directly triggered workflow, not reusable workflows called via | |
| # workflow_call. By triggering build.yaml directly, npm sees build.yaml | |
| # as the entry point and validates against it. | |
| publish-npm: | |
| if: github.event_name == 'push' | |
| needs: [build-packages] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: write | |
| steps: | |
| - name: Trigger build.yaml workflow | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| // Determine tag based on ref type | |
| let tag; | |
| if (context.payload.ref && context.payload.ref.startsWith('refs/tags/')) { | |
| tag = 'latest'; | |
| } else { | |
| tag = 'dev'; | |
| } | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'build.yaml', | |
| ref: context.ref, | |
| inputs: { | |
| run_id: '${{ github.run_id }}', | |
| tag: tag | |
| } | |
| }); | |
| console.log(`Triggered build.yaml workflow with run_id=${{ github.run_id }}, tag=${tag}`); | |
| publish-docs: | |
| if: github.event_name == 'push' | |
| needs: [publish-jsr, determine-version] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| pages: write | |
| deployments: write | |
| statuses: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-mise | |
| - run: | | |
| set -ex | |
| if [[ "$GITHUB_REF_TYPE" = "tag" ]]; then | |
| EXTRA_NAV_TEXT=Unstable \ | |
| EXTRA_NAV_LINK="$UNSTABLE_DOCS_URL" \ | |
| SITEMAP_HOSTNAME="$STABLE_DOCS_URL" \ | |
| JSR_REF_VERSION=stable \ | |
| pnpm run build | |
| else | |
| EXTRA_NAV_TEXT=Stable \ | |
| EXTRA_NAV_LINK="$STABLE_DOCS_URL" \ | |
| SITEMAP_HOSTNAME="$UNSTABLE_DOCS_URL" \ | |
| JSR_REF_VERSION=unstable \ | |
| pnpm run build | |
| fi | |
| env: | |
| SHORT_VERSION: ${{ needs.determine-version.outputs.short_version }} | |
| PLAUSIBLE_DOMAIN: ${{ secrets.PLAUSIBLE_DOMAIN }} | |
| STABLE_DOCS_URL: ${{ vars.STABLE_DOCS_URL }} | |
| UNSTABLE_DOCS_URL: ${{ vars.UNSTABLE_DOCS_URL }} | |
| working-directory: ${{ github.workspace }}/docs/ | |
| - uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: docs/.vitepress/dist | |
| - id: deployment | |
| if: github.ref_type == 'tag' | |
| uses: actions/deploy-pages@v4 | |
| - if: github.ref == 'refs/heads/main' | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| gitHubToken: ${{ github.token }} | |
| command: >- | |
| pages deploy .vitepress/dist | |
| --project-name=${{ vars.CLOUDFLARE_PROJECT_NAME }} | |
| packageManager: pnpm | |
| workingDirectory: ${{ github.workspace }}/docs/ | |
| # cSpell: ignore submark softprops npmjs deployctl nwtgck thollander elif |