feat: add tool list option to tools node (#90) #325
This file contains 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: EinoTests | |
on: | |
pull_request: | |
push: | |
branches: | |
- main | |
env: | |
DEFAULT_GO_VERSION: "1.18" | |
jobs: | |
unit-test: | |
name: eino-unit-test | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
repository-projects: write | |
env: | |
COVERAGE_FILE: coverage.out | |
BREAKDOWN_FILE: main.breakdown | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.DEFAULT_GO_VERSION }} | |
- name: Exec Go Test | |
run: | | |
modules=`find . -name "go.mod" -exec dirname {} \;` | |
echo $modules | |
list="" | |
coverpkg="" | |
if [[ ! -f "go.work" ]];then go work init;fi | |
for module in $modules; do go work use $module; list=$module"/... "$list; coverpkg=$module"/...,"$coverpkg; done | |
go work sync | |
go test -race -v -coverprofile=${{ env.COVERAGE_FILE }} -gcflags="all=-l -N" -coverpkg=$coverpkg $list | |
- name: Download Artifact (main.breakdown) | |
id: download-main-breakdown | |
uses: actions/download-artifact@v4 | |
continue-on-error: true | |
with: | |
name: ${{ env.BREAKDOWN_FILE }} | |
- name: Create main.breakdown If Not Exist | |
run: | | |
if [ ! -f ${{ env.BREAKDOWN_FILE }} ]; then | |
echo "${{ env.BREAKDOWN_FILE }} not found. Creating an empty file." | |
touch ${{ env.BREAKDOWN_FILE }} | |
else | |
echo "${{ env.BREAKDOWN_FILE }} found." | |
fi | |
- name: Calculate Coverage | |
id: coverage | |
uses: vladopajic/go-test-coverage@v2 | |
with: | |
config: ./.testcoverage.yml | |
profile: ${{ env.COVERAGE_FILE}} | |
breakdown-file-name: ${{ github.ref_name == 'main' && env.BREAKDOWN_FILE || '' }} | |
diff-base-breakdown-file-name: ${{ env.BREAKDOWN_FILE }} | |
# to generate and embed coverage badges in markdown files | |
git-token: ${{ github.ref_name == 'main' && secrets.GITHUB_TOKEN || '' }} | |
git-branch: badges | |
- name: Upload Artifact (main.breakdown) | |
uses: actions/upload-artifact@v4 | |
if: github.ref_name == 'main' | |
with: | |
name: ${{ env.BREAKDOWN_FILE }} | |
path: ${{ env.BREAKDOWN_FILE }} | |
if-no-files-found: error | |
- name: Find If coverage Report Exist | |
if: ${{ github.event.pull_request.number != null }} | |
uses: peter-evans/find-comment@v3 | |
id: fc | |
with: | |
issue-number: ${{ github.event.pull_request.number }} | |
comment-author: 'github-actions[bot]' | |
body-includes: '📊 Coverage Report' | |
- name: Send Coverage Report | |
if: ${{ github.event.pull_request.number != null }} | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
issue-number: ${{ github.event.pull_request.number }} | |
comment-id: ${{ steps.fc.outputs.comment-id || '' }} | |
edit-mode: replace | |
body: | | |
## 📊 Coverage Report: | |
``` | |
${{ steps.coverage.outputs.report && fromJSON(steps.coverage.outputs.report) || 'No coverage report available' }} | |
``` | |
- name: Check Coverage | |
if: steps.coverage.outcome == 'failure' | |
shell: bash | |
run: echo "coverage check failed" && exit 1 | |
benchmark-test: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
repository-projects: write | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ env.DEFAULT_GO_VERSION }} | |
- name: Run Benchmark Tests | |
run: go test -bench=. -benchmem -run=none ./... | |
compatibility-test: | |
strategy: | |
matrix: | |
go: [ "1.19", "1.20", "1.21", "1.22" ] | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
repository-projects: write | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ matrix.go }} | |
cache: true | |
- name: Compatibility Test | |
run: | | |
# just basic unit test, no coverage report | |
go test -race ./... | |
api-compatibility: | |
name: api-compatibility-check | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
repository-projects: write | |
if: github.event_name == 'pull_request' | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Set up Go | |
uses: actions/setup-go@v5 | |
with: | |
go-version: "1.22" | |
- name: Install go-apidiff | |
run: go install github.com/joelanford/[email protected] | |
- name: Check API compatibility | |
id: apidiff | |
run: | | |
BASE_SHA=${{ github.event.pull_request.base.sha }} | |
HEAD_SHA=${{ github.event.pull_request.head.sha }} | |
echo "Checking API compatibility between $BASE_SHA and $HEAD_SHA" | |
go mod tidy | |
if ! DIFF_OUTPUT=$(go-apidiff $BASE_SHA $HEAD_SHA 2>&1); then | |
echo "go-apidiff output: $DIFF_OUTPUT" | |
fi | |
echo "diff_output<<EOF" >> $GITHUB_ENV | |
echo "$DIFF_OUTPUT" >> $GITHUB_ENV | |
echo "EOF" >> $GITHUB_ENV | |
if echo "$DIFF_OUTPUT" | grep -q "Incompatible changes:"; then | |
echo "has_breaking_changes=true" >> $GITHUB_OUTPUT | |
else | |
echo "has_breaking_changes=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Create Review Thread | |
if: steps.apidiff.outputs.has_breaking_changes == 'true' | |
continue-on-error: true | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const reviewComments = await github.rest.pulls.listReviewComments({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: context.issue.number | |
}); | |
const existingPackageComments = new Map(); | |
for (const comment of reviewComments.data) { | |
if (comment.body.includes('Breaking API Changes Detected')) { | |
const packageMatch = comment.body.match(/Package: `([^`]+)`/); | |
if (packageMatch) { | |
const pkg = packageMatch[1]; | |
if (!existingPackageComments.has(pkg)) { | |
existingPackageComments.set(pkg, new Set()); | |
} | |
existingPackageComments.get(pkg).add(comment.path); | |
} | |
} | |
} | |
const files = await github.rest.pulls.listFiles({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: context.issue.number | |
}); | |
const diffOutput = process.env.diff_output || ''; | |
const breakingChanges = new Map(); | |
let currentPackage = ''; | |
let isInIncompatibleSection = false; | |
const lines = diffOutput.split('\n'); | |
for (let i = 0; i < lines.length; i++) { | |
const line = lines[i].trim(); | |
if (line.startsWith('github.com/')) { | |
currentPackage = line; | |
if (!breakingChanges.has(currentPackage)) { | |
breakingChanges.set(currentPackage, []); | |
} | |
continue; | |
} | |
if (line === 'Incompatible changes:') { | |
isInIncompatibleSection = true; | |
continue; | |
} | |
if (line === '') { | |
isInIncompatibleSection = false; | |
continue; | |
} | |
if (isInIncompatibleSection && line.startsWith('- ')) { | |
const change = line.substring(2); | |
if (currentPackage) { | |
breakingChanges.get(currentPackage).push(change); | |
} | |
} | |
} | |
const changedFiles = files.data; | |
for (const [pkg, changes] of breakingChanges) { | |
if (changes.length === 0) continue; | |
const pkgPath = pkg.split('/').slice(3).join('/'); | |
const matchingFile = changedFiles.find(file => | |
file.filename.includes(pkgPath) | |
) || changedFiles[0]; | |
const hasCommentForPackage = existingPackageComments.has(pkg) && | |
existingPackageComments.get(pkg).has(matchingFile.filename); | |
if (matchingFile && !hasCommentForPackage) { | |
const changesList = changes.map(change => { | |
const [name, desc] = change.split(':').map(s => s.trim()); | |
return `- **${name}:** ${desc}`; | |
}).join('\n'); | |
const commentBody = [ | |
'🚨 **Breaking API Changes Detected**', | |
'', | |
`Package: \`${pkg}\``, | |
'', | |
'Incompatible changes:', | |
changesList, | |
'', | |
'<details>', | |
'<summary>Review Guidelines</summary>', | |
'', | |
'Please ensure that:', | |
'- The changes are absolutely necessary', | |
'- They are properly documented', | |
'- Migration guides are provided if needed', | |
'</details>', | |
'', | |
'⚠️ Please resolve this thread after reviewing the breaking changes.' | |
].join('\n'); | |
await github.rest.pulls.createReview({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: context.issue.number, | |
event: 'COMMENT', | |
comments: [{ | |
path: matchingFile.filename, | |
position: matchingFile.patch ? matchingFile.patch.split('\n').findIndex(line => line.startsWith('+')) + 1 : 1, | |
body: commentBody | |
}] | |
}); | |
if (!existingPackageComments.has(pkg)) { | |
existingPackageComments.set(pkg, new Set()); | |
} | |
existingPackageComments.get(pkg).add(matchingFile.filename); | |
} | |
} |