ghcr_runtime.yml 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # Workflow that builds, tests and then pushes the runtime docker images to the ghcr.io repository
  2. name: Build, Test and Publish Runtime Image
  3. # Only run one workflow of the same group at a time.
  4. # There can be at most one running and one pending job in a concurrency group at any time.
  5. concurrency:
  6. group: ${{ github.workflow }}-${{ github.ref }}
  7. cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
  8. on:
  9. push:
  10. branches:
  11. - main
  12. tags:
  13. - '*'
  14. pull_request:
  15. workflow_dispatch:
  16. inputs:
  17. reason:
  18. description: 'Reason for manual trigger'
  19. required: true
  20. default: ''
  21. jobs:
  22. # Builds the runtime Docker images
  23. ghcr_build_runtime:
  24. name: Build Image
  25. runs-on: ubuntu-latest
  26. permissions:
  27. contents: read
  28. packages: write
  29. strategy:
  30. matrix:
  31. base_image: ['nikolaik/python-nodejs:python3.11-nodejs22', 'python:3.11-bookworm', 'node:22-bookworm']
  32. steps:
  33. - name: Checkout
  34. uses: actions/checkout@v4
  35. - name: Free Disk Space (Ubuntu)
  36. uses: jlumbroso/free-disk-space@main
  37. with:
  38. # this might remove tools that are actually needed,
  39. # if set to "true" but frees about 6 GB
  40. tool-cache: true
  41. # all of these default to true, but feel free to set to
  42. # "false" if necessary for your workflow
  43. android: true
  44. dotnet: true
  45. haskell: true
  46. large-packages: true
  47. docker-images: false
  48. swap-storage: true
  49. - name: Set up QEMU
  50. uses: docker/setup-qemu-action@v3
  51. - name: Login to GHCR
  52. uses: docker/login-action@v3
  53. with:
  54. registry: ghcr.io
  55. username: ${{ github.repository_owner }}
  56. password: ${{ secrets.GITHUB_TOKEN }}
  57. - name: Set up Docker Buildx
  58. id: buildx
  59. uses: docker/setup-buildx-action@v3
  60. - name: Install poetry via pipx
  61. run: pipx install poetry
  62. - name: Set up Python
  63. uses: actions/setup-python@v5
  64. with:
  65. python-version: '3.11'
  66. cache: 'poetry'
  67. - name: Install Python dependencies using Poetry
  68. run: make install-python-dependencies
  69. - name: Create source distribution and Dockerfile
  70. run: poetry run python3 openhands/runtime/utils/runtime_build.py --base_image ${{ matrix.base_image }} --build_folder containers/runtime --force_rebuild
  71. - name: Build and export image
  72. id: build
  73. run: |
  74. suffix=$(echo "${{ matrix.base_image }}" | cut -d ':' -f 1 | cut -d '/' -f 1)
  75. ./containers/build.sh runtime ${{ github.repository_owner }} --push $suffix
  76. # Run unit tests with the EventStream runtime Docker images
  77. test_runtime:
  78. name: Test Runtime
  79. runs-on: ubuntu-latest
  80. needs: [ghcr_build_runtime]
  81. strategy:
  82. matrix:
  83. base_image: ['nikolaik', 'python', 'node']
  84. steps:
  85. - uses: actions/checkout@v4
  86. - name: Free Disk Space (Ubuntu)
  87. uses: jlumbroso/free-disk-space@main
  88. with:
  89. tool-cache: true
  90. android: true
  91. dotnet: true
  92. haskell: true
  93. large-packages: true
  94. swap-storage: true
  95. - name: Install poetry via pipx
  96. run: pipx install poetry
  97. - name: Set up Python
  98. uses: actions/setup-python@v5
  99. with:
  100. python-version: '3.11'
  101. cache: 'poetry'
  102. - name: Install Python dependencies using Poetry
  103. run: make install-python-dependencies
  104. - name: Run runtime tests
  105. run: |
  106. git_hash=$(git rev-parse --short "$GITHUB_SHA")
  107. image_name=ghcr.io/${{ github.repository_owner }}/runtime:$git_hash-${{ matrix.base_image }}
  108. image_name=$(echo $image_name | tr '[:upper:]' '[:lower:]')
  109. TEST_RUNTIME=eventstream \
  110. SANDBOX_USER_ID=$(id -u) \
  111. SANDBOX_CONTAINER_IMAGE=$image_name \
  112. TEST_IN_CI=true \
  113. poetry run pytest --cov=agenthub --cov=openhands --cov-report=xml -s ./tests/runtime
  114. - name: Upload coverage to Codecov
  115. uses: codecov/codecov-action@v4
  116. env:
  117. CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
  118. # Run integration tests with the eventstream runtime Docker image
  119. runtime_integration_tests_on_linux:
  120. name: Runtime Integration Tests on Linux
  121. runs-on: ubuntu-latest
  122. needs: [ghcr_build_runtime]
  123. strategy:
  124. fail-fast: false
  125. matrix:
  126. base_image: ['nikolaik', 'python', 'node']
  127. steps:
  128. - uses: actions/checkout@v4
  129. - name: Install poetry via pipx
  130. run: pipx install poetry
  131. - name: Set up Python
  132. uses: actions/setup-python@v5
  133. with:
  134. python-version: '3.11'
  135. cache: 'poetry'
  136. - name: Install Python dependencies using Poetry
  137. run: make install-python-dependencies
  138. - name: Run integration tests
  139. run: |
  140. git_hash=$(git rev-parse --short "$GITHUB_SHA")
  141. image_name=ghcr.io/${{ github.repository_owner }}/runtime:$git_hash-${{ matrix.base_image }}
  142. image_name=$(echo $image_name | tr '[:upper:]' '[:lower:]')
  143. TEST_RUNTIME=eventstream \
  144. SANDBOX_USER_ID=$(id -u) \
  145. SANDBOX_CONTAINER_IMAGE=$image_name \
  146. TEST_IN_CI=true \
  147. TEST_ONLY=true \
  148. ./tests/integration/regenerate.sh
  149. - name: Upload coverage to Codecov
  150. uses: codecov/codecov-action@v4
  151. env:
  152. CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
  153. # Checks that all runtime tests have passed
  154. all_runtime_tests_passed:
  155. name: All Runtime Tests Passed
  156. runs-on: ubuntu-latest
  157. needs: [test_runtime, runtime_integration_tests_on_linux]
  158. steps:
  159. - name: All tests passed
  160. run: echo "All runtime tests have passed successfully!"