wip: [01-stabilize] paused at task 1/1 - OCR Hallucination Immune logic via Semantic delta window and fret-isolation
This commit is contained in:
44
.agent/services/mcp-core/.github/pull_request_template.md
vendored
Normal file
44
.agent/services/mcp-core/.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<!-- Provide a brief description of your changes -->
|
||||
|
||||
## Description
|
||||
|
||||
## Publishing Your Server
|
||||
|
||||
**Note: We are no longer accepting PRs to add servers to the README.** Instead, please publish your server to the [MCP Server Registry](https://github.com/modelcontextprotocol/registry) to make it discoverable to the MCP ecosystem.
|
||||
|
||||
To publish your server, follow the [quickstart guide](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx). You can browse published servers at [https://registry.modelcontextprotocol.io/](https://registry.modelcontextprotocol.io/).
|
||||
|
||||
## Server Details
|
||||
<!-- If modifying an existing server, provide details -->
|
||||
- Server: <!-- e.g., filesystem, github -->
|
||||
- Changes to: <!-- e.g., tools, resources, prompts -->
|
||||
|
||||
## Motivation and Context
|
||||
<!-- Why is this change needed? What problem does it solve? -->
|
||||
|
||||
## How Has This Been Tested?
|
||||
<!-- Have you tested this with an LLM client? Which scenarios were tested? -->
|
||||
|
||||
## Breaking Changes
|
||||
<!-- Will users need to update their MCP client configurations? -->
|
||||
|
||||
## Types of changes
|
||||
<!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||
- [ ] Documentation update
|
||||
|
||||
## Checklist
|
||||
<!-- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
- [ ] I have read the [MCP Protocol Documentation](https://modelcontextprotocol.io)
|
||||
- [ ] My changes follows MCP security best practices
|
||||
- [ ] I have updated the server's README accordingly
|
||||
- [ ] I have tested this with an LLM client
|
||||
- [ ] My code follows the repository's style guidelines
|
||||
- [ ] New and existing tests pass locally
|
||||
- [ ] I have added appropriate error handling
|
||||
- [ ] I have documented all environment variables and configuration options
|
||||
|
||||
## Additional context
|
||||
<!-- Add any other context, implementation notes, or design decisions -->
|
||||
49
.agent/services/mcp-core/.github/workflows/claude.yml
vendored
Normal file
49
.agent/services/mcp-core/.github/workflows/claude.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Claude Code
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: read
|
||||
id-token: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code
|
||||
id: claude
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
|
||||
# Allow Claude to read CI results on PRs
|
||||
additional_permissions: |
|
||||
actions: read
|
||||
|
||||
# Trigger when assigned to an issue
|
||||
assignee_trigger: "claude"
|
||||
|
||||
claude_args: |
|
||||
--mcp-config .mcp.json
|
||||
--allowedTools "Bash,mcp__mcp-docs,WebFetch"
|
||||
--append-system-prompt "If posting a comment to GitHub, give a concise summary of the comment at the top and put all the details in a <details> block. When working on MCP-related code or reviewing MCP-related changes, use the mcp-docs MCP server to look up the latest protocol documentation. For schema details, reference https://github.com/modelcontextprotocol/modelcontextprotocol/tree/main/schema which contains versioned schemas in JSON (schema.json) and TypeScript (schema.ts) formats."
|
||||
121
.agent/services/mcp-core/.github/workflows/python.yml
vendored
Normal file
121
.agent/services/mcp-core/.github/workflows/python.yml
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
name: Python
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
detect-packages:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
packages: ${{ steps.find-packages.outputs.packages }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Find Python packages
|
||||
id: find-packages
|
||||
working-directory: src
|
||||
run: |
|
||||
PACKAGES=$(find . -name pyproject.toml -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
|
||||
|
||||
test:
|
||||
needs: [detect-packages]
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Test ${{ matrix.package }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version-file: "src/${{ matrix.package }}/.python-version"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv sync --frozen --all-extras --dev
|
||||
|
||||
- name: Check if tests exist
|
||||
id: check-tests
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: |
|
||||
if [ -d "tests" ] || [ -d "test" ] || grep -q "pytest" pyproject.toml; then
|
||||
echo "has-tests=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "has-tests=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
if: steps.check-tests.outputs.has-tests == 'true'
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv run pytest
|
||||
|
||||
build:
|
||||
needs: [detect-packages, test]
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Build ${{ matrix.package }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version-file: "src/${{ matrix.package }}/.python-version"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv sync --locked --all-extras --dev
|
||||
|
||||
- name: Run pyright
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv run --frozen pyright
|
||||
|
||||
- name: Build package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv build
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: dist-${{ matrix.package }}
|
||||
path: src/${{ matrix.package }}/dist/
|
||||
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, detect-packages]
|
||||
if: github.event_name == 'release'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Publish ${{ matrix.package }}
|
||||
|
||||
environment: release
|
||||
permissions:
|
||||
id-token: write # Required for trusted publishing
|
||||
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: dist-${{ matrix.package }}
|
||||
path: dist/
|
||||
|
||||
- name: Publish package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
111
.agent/services/mcp-core/.github/workflows/readme-pr-check.yml
vendored
Normal file
111
.agent/services/mcp-core/.github/workflows/readme-pr-check.yml
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
name: README PR Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
paths:
|
||||
- 'README.md'
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
check-readme-only:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Check files and comment if README-only
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
|
||||
const { data: files } = await github.rest.pulls.listFiles({ owner, repo, pull_number: prNumber });
|
||||
|
||||
if (files.length !== 1 || files[0].filename !== 'README.md') {
|
||||
console.log('PR modifies files other than README, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we've already commented
|
||||
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
|
||||
if (comments.some(c => c.user.login === 'github-actions[bot]' && c.body.includes('no longer accepting PRs to add new servers'))) {
|
||||
console.log('Already commented on this PR, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['readme: pending'] });
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: prNumber,
|
||||
body: [
|
||||
'Thanks for your contribution!',
|
||||
'',
|
||||
'**We are no longer accepting PRs to add new servers to the README.** The server lists are deprecated and will eventually be removed entirely, replaced by the registry.',
|
||||
'',
|
||||
'👉 **To add a new MCP server:** Please publish it to the [MCP Server Registry](https://github.com/modelcontextprotocol/registry) instead. You can browse published servers at [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io/).',
|
||||
'',
|
||||
'👉 **If this PR updates or removes an existing entry:** We do still accept these changes. Please reply with `/i-promise-this-is-not-a-new-server` to continue.',
|
||||
'',
|
||||
'If this PR is adding a new server, please close it and submit to the registry instead.',
|
||||
].join('\n'),
|
||||
});
|
||||
|
||||
handle-confirmation:
|
||||
if: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/i-promise-this-is-not-a-new-server')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Swap labels and minimize comments
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const prNumber = context.payload.issue.number;
|
||||
|
||||
// Check if pending label exists
|
||||
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number: prNumber });
|
||||
if (!labels.some(l => l.name === 'readme: pending')) {
|
||||
console.log('No pending label found, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
// Swap labels
|
||||
try {
|
||||
await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: 'readme: pending' });
|
||||
} catch (e) {}
|
||||
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['readme: ready for review'] });
|
||||
|
||||
// Find the bot's original comment
|
||||
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
|
||||
const botComment = comments.find(c =>
|
||||
c.user.login === 'github-actions[bot]' &&
|
||||
c.body.includes('no longer accepting PRs to add new servers')
|
||||
);
|
||||
|
||||
// Minimize both comments via GraphQL
|
||||
const minimizeComment = async (nodeId) => {
|
||||
await github.graphql(`
|
||||
mutation($id: ID!) {
|
||||
minimizeComment(input: {subjectId: $id, classifier: RESOLVED}) {
|
||||
minimizedComment { isMinimized }
|
||||
}
|
||||
}
|
||||
`, { id: nodeId });
|
||||
};
|
||||
|
||||
if (botComment) {
|
||||
await minimizeComment(botComment.node_id);
|
||||
}
|
||||
|
||||
// Only minimize user's comment if it's just the command
|
||||
const userComment = context.payload.comment.body.trim();
|
||||
if (userComment === '/i-promise-this-is-not-a-new-server') {
|
||||
await minimizeComment(context.payload.comment.node_id);
|
||||
}
|
||||
222
.agent/services/mcp-core/.github/workflows/release.yml
vendored
Normal file
222
.agent/services/mcp-core/.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
name: Automatic Release Creation
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
|
||||
jobs:
|
||||
create-metadata:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'modelcontextprotocol'
|
||||
outputs:
|
||||
hash: ${{ steps.last-release.outputs.hash }}
|
||||
version: ${{ steps.create-version.outputs.version}}
|
||||
npm_packages: ${{ steps.create-npm-packages.outputs.npm_packages}}
|
||||
pypi_packages: ${{ steps.create-pypi-packages.outputs.pypi_packages}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- 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}"
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Create version name
|
||||
id: create-version
|
||||
run: |
|
||||
VERSION=$(uv run --script scripts/release.py generate-version)
|
||||
echo "version $VERSION"
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create notes
|
||||
run: |
|
||||
HASH="${{ steps.last-release.outputs.hash }}"
|
||||
uv run --script scripts/release.py generate-notes --directory src/ $HASH > RELEASE_NOTES.md
|
||||
cat RELEASE_NOTES.md
|
||||
|
||||
- name: Release notes
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: release-notes
|
||||
path: RELEASE_NOTES.md
|
||||
|
||||
- name: Create python matrix
|
||||
id: create-pypi-packages
|
||||
run: |
|
||||
HASH="${{ steps.last-release.outputs.hash }}"
|
||||
PYPI=$(uv run --script scripts/release.py generate-matrix --pypi --directory src $HASH)
|
||||
echo "pypi_packages $PYPI"
|
||||
echo "pypi_packages=$PYPI" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create npm matrix
|
||||
id: create-npm-packages
|
||||
run: |
|
||||
HASH="${{ steps.last-release.outputs.hash }}"
|
||||
NPM=$(uv run --script scripts/release.py generate-matrix --npm --directory src $HASH)
|
||||
echo "npm_packages $NPM"
|
||||
echo "npm_packages=$NPM" >> $GITHUB_OUTPUT
|
||||
|
||||
update-packages:
|
||||
needs: [create-metadata]
|
||||
if: ${{ needs.create-metadata.outputs.npm_packages != '[]' || needs.create-metadata.outputs.pypi_packages != '[]' }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
changes_made: ${{ steps.commit.outputs.changes_made }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Update packages
|
||||
run: |
|
||||
HASH="${{ needs.create-metadata.outputs.hash }}"
|
||||
uv run --script scripts/release.py update-packages --directory src/ $HASH
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.name "GitHub Actions"
|
||||
git config --global user.email "actions@github.com"
|
||||
|
||||
- name: Commit changes
|
||||
id: commit
|
||||
run: |
|
||||
VERSION="${{ needs.create-metadata.outputs.version }}"
|
||||
git add -u
|
||||
if git diff-index --quiet HEAD; then
|
||||
echo "changes_made=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
git commit -m 'Automatic update of packages'
|
||||
git tag -a "$VERSION" -m "Release $VERSION"
|
||||
git push origin "$VERSION"
|
||||
echo "changes_made=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
publish-pypi:
|
||||
needs: [update-packages, create-metadata]
|
||||
if: ${{ needs.create-metadata.outputs.pypi_packages != '[]' && needs.create-metadata.outputs.pypi_packages != '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.create-metadata.outputs.pypi_packages) }}
|
||||
name: Build ${{ matrix.package }}
|
||||
environment: release
|
||||
permissions:
|
||||
id-token: write # Required for trusted publishing
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.create-metadata.outputs.version }}
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version-file: "src/${{ matrix.package }}/.python-version"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv sync --frozen --all-extras --dev
|
||||
|
||||
- name: Run pyright
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv run --frozen pyright
|
||||
|
||||
- name: Build package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: uv build
|
||||
|
||||
- name: Publish package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages-dir: src/${{ matrix.package }}/dist
|
||||
|
||||
publish-npm:
|
||||
needs: [update-packages, create-metadata]
|
||||
if: ${{ needs.create-metadata.outputs.npm_packages != '[]' && needs.create-metadata.outputs.npm_packages != '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.create-metadata.outputs.npm_packages) }}
|
||||
name: Build ${{ matrix.package }}
|
||||
environment: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.create-metadata.outputs.version }}
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm ci
|
||||
|
||||
- name: Check if version exists on npm
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: |
|
||||
VERSION=$(jq -r .version package.json)
|
||||
if npm view --json | jq -e --arg version "$VERSION" '[.[]][0].versions | contains([$version])'; then
|
||||
echo "Version $VERSION already exists on npm"
|
||||
exit 1
|
||||
fi
|
||||
echo "Version $VERSION is new, proceeding with publish"
|
||||
|
||||
- name: Build package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm run build
|
||||
|
||||
- name: Publish package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: |
|
||||
npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
create-release:
|
||||
needs: [update-packages, create-metadata, publish-pypi, publish-npm]
|
||||
if: |
|
||||
always() &&
|
||||
needs.update-packages.outputs.changes_made == 'true' &&
|
||||
(needs.publish-pypi.result == 'success' || needs.publish-npm.result == 'success')
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Download release notes
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: release-notes
|
||||
|
||||
- name: Create release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN}}
|
||||
run: |
|
||||
VERSION="${{ needs.create-metadata.outputs.version }}"
|
||||
gh release create "$VERSION" \
|
||||
--title "Release $VERSION" \
|
||||
--notes-file RELEASE_NOTES.md
|
||||
|
||||
102
.agent/services/mcp-core/.github/workflows/typescript.yml
vendored
Normal file
102
.agent/services/mcp-core/.github/workflows/typescript.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: TypeScript
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
detect-packages:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
packages: ${{ steps.find-packages.outputs.packages }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Find JS packages
|
||||
id: find-packages
|
||||
working-directory: src
|
||||
run: |
|
||||
PACKAGES=$(find . -name package.json -not -path "*/node_modules/*" -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]')
|
||||
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
|
||||
|
||||
test:
|
||||
needs: [detect-packages]
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Test ${{ matrix.package }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm test --if-present
|
||||
|
||||
build:
|
||||
needs: [detect-packages, test]
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Build ${{ matrix.package }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm ci
|
||||
|
||||
- name: Build package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm run build
|
||||
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, detect-packages]
|
||||
if: github.event_name == 'release'
|
||||
environment: release
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
|
||||
name: Publish ${{ matrix.package }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm ci
|
||||
|
||||
- name: Publish package
|
||||
working-directory: src/${{ matrix.package }}
|
||||
run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
Reference in New Issue
Block a user