test-agents.yml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. name: Test Agents
  2. on:
  3. pull_request:
  4. branches: [ main, dev ]
  5. paths:
  6. - '.opencode/**'
  7. - 'evals/**'
  8. - '.github/workflows/test-agents.yml'
  9. push:
  10. branches: [ main ]
  11. workflow_dispatch:
  12. jobs:
  13. # Check if this is a PR merge commit (skip tests if so - they already ran on PR)
  14. check-trigger:
  15. name: Check Trigger Type
  16. runs-on: ubuntu-latest
  17. outputs:
  18. should_test: ${{ steps.check.outputs.should_test }}
  19. should_bump: ${{ steps.check.outputs.should_bump }}
  20. steps:
  21. - name: Determine if tests should run
  22. id: check
  23. run: |
  24. # For PRs, always run tests
  25. if [ "${{ github.event_name }}" == "pull_request" ]; then
  26. echo "should_test=true" >> $GITHUB_OUTPUT
  27. echo "should_bump=false" >> $GITHUB_OUTPUT
  28. echo "PR detected - will run tests"
  29. exit 0
  30. fi
  31. # For workflow_dispatch, always run tests
  32. if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
  33. echo "should_test=true" >> $GITHUB_OUTPUT
  34. echo "should_bump=false" >> $GITHUB_OUTPUT
  35. echo "Manual trigger - will run tests"
  36. exit 0
  37. fi
  38. # For push events, check if it's a PR merge
  39. COMMIT_MSG="${{ github.event.head_commit.message }}"
  40. # PR merges have messages like "Merge pull request #123" or contain (#123)
  41. if echo "$COMMIT_MSG" | grep -qE "^Merge pull request #|^.*\(#[0-9]+\)$"; then
  42. echo "should_test=false" >> $GITHUB_OUTPUT
  43. echo "should_bump=true" >> $GITHUB_OUTPUT
  44. echo "PR merge detected - skipping tests, will bump version"
  45. # Skip version bump commits
  46. elif echo "$COMMIT_MSG" | grep -qE "^\[skip ci\]|chore: bump version"; then
  47. echo "should_test=false" >> $GITHUB_OUTPUT
  48. echo "should_bump=false" >> $GITHUB_OUTPUT
  49. echo "Version bump commit - skipping everything"
  50. else
  51. echo "should_test=true" >> $GITHUB_OUTPUT
  52. echo "should_bump=true" >> $GITHUB_OUTPUT
  53. echo "Direct push detected - will run tests and bump version"
  54. fi
  55. test-openagent:
  56. name: Test OpenAgent
  57. runs-on: ubuntu-latest
  58. needs: check-trigger
  59. if: needs.check-trigger.outputs.should_test == 'true'
  60. timeout-minutes: 15
  61. steps:
  62. - name: Checkout code
  63. uses: actions/checkout@v4
  64. - name: Setup Node.js
  65. uses: actions/setup-node@v4
  66. with:
  67. node-version: '20'
  68. cache: 'npm'
  69. cache-dependency-path: 'evals/framework/package-lock.json'
  70. # Install the OpenCode CLI (from opencode.ai, NOT our install.sh)
  71. # Our install.sh only installs agents/commands/tools, not the CLI binary
  72. # The @opencode-ai/sdk spawns `opencode serve` internally, so CLI is required
  73. - name: Install OpenCode CLI
  74. run: |
  75. npm install -g opencode-ai
  76. which opencode
  77. opencode --version
  78. # Install our OpenAgents components (agents, commands, tools)
  79. - name: Install OpenAgents Components
  80. run: bash install.sh essential --install-dir .opencode
  81. - name: Install dependencies
  82. working-directory: evals/framework
  83. run: npm install
  84. - name: Build framework
  85. working-directory: evals/framework
  86. run: npm run build
  87. - name: Run OpenAgent smoke test
  88. run: npm run test:ci:openagent
  89. env:
  90. CI: true
  91. - name: Upload test results
  92. if: always()
  93. uses: actions/upload-artifact@v4
  94. with:
  95. name: openagent-results
  96. path: evals/results/
  97. retention-days: 30
  98. test-opencoder:
  99. name: Test OpenCoder
  100. runs-on: ubuntu-latest
  101. needs: check-trigger
  102. if: needs.check-trigger.outputs.should_test == 'true'
  103. timeout-minutes: 15
  104. steps:
  105. - name: Checkout code
  106. uses: actions/checkout@v4
  107. - name: Setup Node.js
  108. uses: actions/setup-node@v4
  109. with:
  110. node-version: '20'
  111. cache: 'npm'
  112. cache-dependency-path: 'evals/framework/package-lock.json'
  113. # Install the OpenCode CLI (from opencode.ai, NOT our install.sh)
  114. # Our install.sh only installs agents/commands/tools, not the CLI binary
  115. # The @opencode-ai/sdk spawns `opencode serve` internally, so CLI is required
  116. - name: Install OpenCode CLI
  117. run: |
  118. npm install -g opencode-ai
  119. which opencode
  120. opencode --version
  121. # Install our OpenAgents components (agents, commands, tools)
  122. - name: Install OpenAgents Components
  123. run: bash install.sh essential --install-dir .opencode
  124. - name: Install dependencies
  125. working-directory: evals/framework
  126. run: npm install
  127. - name: Build framework
  128. working-directory: evals/framework
  129. run: npm run build
  130. - name: Run OpenCoder smoke test
  131. run: npm run test:ci:opencoder
  132. env:
  133. CI: true
  134. - name: Upload test results
  135. if: always()
  136. uses: actions/upload-artifact@v4
  137. with:
  138. name: opencoder-results
  139. path: evals/results/
  140. retention-days: 30
  141. report-results:
  142. name: Report Test Results
  143. runs-on: ubuntu-latest
  144. needs: [check-trigger, test-openagent, test-opencoder]
  145. if: always() && needs.check-trigger.outputs.should_test == 'true'
  146. steps:
  147. - name: Download OpenAgent results
  148. uses: actions/download-artifact@v4
  149. with:
  150. name: openagent-results
  151. path: results/openagent
  152. continue-on-error: true
  153. - name: Download OpenCoder results
  154. uses: actions/download-artifact@v4
  155. with:
  156. name: opencoder-results
  157. path: results/opencoder
  158. continue-on-error: true
  159. - name: Display results summary
  160. run: |
  161. echo "## Test Results Summary" >> $GITHUB_STEP_SUMMARY
  162. echo "" >> $GITHUB_STEP_SUMMARY
  163. if [ -f results/openagent/latest.json ]; then
  164. echo "### OpenAgent" >> $GITHUB_STEP_SUMMARY
  165. cat results/openagent/latest.json | jq -r '"- Passed: \(.passed)\n- Failed: \(.failed)\n- Total: \(.total)"' >> $GITHUB_STEP_SUMMARY
  166. fi
  167. if [ -f results/opencoder/latest.json ]; then
  168. echo "" >> $GITHUB_STEP_SUMMARY
  169. echo "### OpenCoder" >> $GITHUB_STEP_SUMMARY
  170. cat results/opencoder/latest.json | jq -r '"- Passed: \(.passed)\n- Failed: \(.failed)\n- Total: \(.total)"' >> $GITHUB_STEP_SUMMARY
  171. fi
  172. auto-version-bump:
  173. name: Auto Version Bump
  174. runs-on: ubuntu-latest
  175. needs: [check-trigger, test-openagent, test-opencoder]
  176. # Run version bump if:
  177. # 1. Tests ran and passed, OR
  178. # 2. This is a PR merge (tests already passed on PR)
  179. if: |
  180. github.event_name == 'push' &&
  181. github.ref == 'refs/heads/main' &&
  182. needs.check-trigger.outputs.should_bump == 'true' &&
  183. (needs.check-trigger.outputs.should_test == 'false' ||
  184. (needs.test-openagent.result == 'success' && needs.test-opencoder.result == 'success'))
  185. permissions:
  186. contents: write
  187. steps:
  188. - name: Checkout code
  189. uses: actions/checkout@v4
  190. with:
  191. fetch-depth: 0
  192. token: ${{ secrets.GITHUB_TOKEN }}
  193. - name: Setup Node.js
  194. uses: actions/setup-node@v4
  195. with:
  196. node-version: '20'
  197. - name: Configure Git
  198. run: |
  199. git config user.name "github-actions[bot]"
  200. git config user.email "github-actions[bot]@users.noreply.github.com"
  201. - name: Determine version bump type
  202. id: bump-type
  203. run: |
  204. # Get the last commit message
  205. COMMIT_MSG=$(git log -1 --pretty=%B)
  206. # Determine bump type from commit message
  207. if echo "$COMMIT_MSG" | grep -qiE "^(feat|feature)\(.*\)!:|^BREAKING CHANGE:|^[a-z]+!:"; then
  208. echo "type=major" >> $GITHUB_OUTPUT
  209. echo "Detected BREAKING CHANGE - bumping major version"
  210. elif echo "$COMMIT_MSG" | grep -qiE "^(feat|feature)(\(.*\))?:"; then
  211. echo "type=minor" >> $GITHUB_OUTPUT
  212. echo "Detected feature - bumping minor version"
  213. elif echo "$COMMIT_MSG" | grep -qiE "^(fix|bugfix)(\(.*\))?:"; then
  214. echo "type=patch" >> $GITHUB_OUTPUT
  215. echo "Detected fix - bumping patch version"
  216. elif echo "$COMMIT_MSG" | grep -qiE "^\[alpha\]"; then
  217. echo "type=alpha" >> $GITHUB_OUTPUT
  218. echo "Detected [alpha] tag - bumping alpha version"
  219. elif echo "$COMMIT_MSG" | grep -qiE "^\[beta\]"; then
  220. echo "type=beta" >> $GITHUB_OUTPUT
  221. echo "Detected [beta] tag - bumping beta version"
  222. elif echo "$COMMIT_MSG" | grep -qiE "^\[rc\]"; then
  223. echo "type=rc" >> $GITHUB_OUTPUT
  224. echo "Detected [rc] tag - bumping rc version"
  225. else
  226. echo "type=patch" >> $GITHUB_OUTPUT
  227. echo "No specific type detected - defaulting to patch version bump"
  228. fi
  229. - name: Bump version
  230. run: |
  231. BUMP_TYPE="${{ steps.bump-type.outputs.type }}"
  232. # Get current version
  233. CURRENT_VERSION=$(cat VERSION)
  234. echo "Current version: $CURRENT_VERSION"
  235. # Bump version in package.json
  236. npm run version:bump:$BUMP_TYPE
  237. # Get new version
  238. NEW_VERSION=$(cat VERSION)
  239. echo "New version: $NEW_VERSION"
  240. # Update CHANGELOG.md
  241. DATE=$(date +%Y-%m-%d)
  242. COMMIT_MSG=$(git log -1 --pretty=%B)
  243. # Create changelog entry
  244. cat > /tmp/changelog_entry.md << EOF
  245. ## [$NEW_VERSION] - $DATE
  246. ### Changes
  247. - $COMMIT_MSG
  248. EOF
  249. # Prepend to CHANGELOG.md (after the header)
  250. if [ -f CHANGELOG.md ]; then
  251. # Insert after the first occurrence of "## ["
  252. awk '/^## \[/ && !found {print; system("cat /tmp/changelog_entry.md"); found=1; next} 1' CHANGELOG.md > /tmp/changelog_new.md
  253. mv /tmp/changelog_new.md CHANGELOG.md
  254. fi
  255. - name: Commit version bump
  256. run: |
  257. NEW_VERSION=$(cat VERSION)
  258. git add VERSION package.json CHANGELOG.md
  259. git commit -m "chore: bump version to v$NEW_VERSION [skip ci]"
  260. git tag "v$NEW_VERSION"
  261. - name: Push changes
  262. run: |
  263. git push origin main --tags
  264. env:
  265. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  266. - name: Create GitHub Release
  267. run: |
  268. NEW_VERSION=$(cat VERSION)
  269. # Extract changelog entry for this version
  270. RELEASE_NOTES=$(awk '/^## \['"$NEW_VERSION"'\]/{flag=1; next} /^## \[/{flag=0} flag' CHANGELOG.md)
  271. # If no specific notes found, use commit message
  272. if [ -z "$RELEASE_NOTES" ]; then
  273. RELEASE_NOTES="Release v$NEW_VERSION"
  274. fi
  275. # Create the release
  276. gh release create "v$NEW_VERSION" \
  277. --title "v$NEW_VERSION" \
  278. --notes "$RELEASE_NOTES" \
  279. --latest
  280. env:
  281. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}