ghcr_app.yml 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # Workflow that builds, tests and then pushes the app docker images to the ghcr.io repository
  2. name: Build and Publish App Image
  3. # Always run on "main"
  4. # Always run on tags
  5. # Always run on PRs
  6. # Can also be triggered manually
  7. on:
  8. push:
  9. branches:
  10. - main
  11. tags:
  12. - '*'
  13. pull_request:
  14. workflow_dispatch:
  15. inputs:
  16. reason:
  17. description: 'Reason for manual trigger'
  18. required: true
  19. default: ''
  20. jobs:
  21. # Builds the OpenHands Docker images
  22. ghcr_build:
  23. name: Build App Image
  24. runs-on: ubuntu-latest
  25. outputs:
  26. tags: ${{ steps.capture-tags.outputs.tags }}
  27. permissions:
  28. contents: read
  29. packages: write
  30. strategy:
  31. matrix:
  32. image: ['openhands']
  33. platform: ['amd64', 'arm64']
  34. steps:
  35. - name: Checkout
  36. uses: actions/checkout@v4
  37. - name: Free Disk Space (Ubuntu)
  38. uses: jlumbroso/free-disk-space@main
  39. with:
  40. # this might remove tools that are actually needed,
  41. # if set to "true" but frees about 6 GB
  42. tool-cache: true
  43. # all of these default to true, but feel free to set to
  44. # "false" if necessary for your workflow
  45. android: true
  46. dotnet: true
  47. haskell: true
  48. large-packages: true
  49. docker-images: false
  50. swap-storage: true
  51. - name: Set up QEMU
  52. uses: docker/setup-qemu-action@v3
  53. - name: Set up Docker Buildx
  54. id: buildx
  55. uses: docker/setup-buildx-action@v3
  56. - name: Build and export image
  57. id: build
  58. run: ./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }} ${{ matrix.platform }}
  59. - name: Capture tags
  60. id: capture-tags
  61. run: |
  62. tags=$(cat tags.txt)
  63. echo "tags=$tags"
  64. echo "tags=$tags" >> $GITHUB_OUTPUT
  65. - name: Upload Docker image as artifact
  66. uses: actions/upload-artifact@v4
  67. with:
  68. name: ${{ matrix.image }}_image_${{ matrix.platform }}
  69. path: /tmp/${{ matrix.image }}_$(echo "${{ steps.capture-tags.outputs.tags }}" | awk '{print $NF}')_${{ matrix.platform }}.tar
  70. retention-days: 14
  71. # Push the OpenHands and sandbox Docker images to the ghcr.io repository
  72. ghcr_push:
  73. runs-on: ubuntu-latest
  74. needs: [ghcr_build]
  75. if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main')
  76. env:
  77. tags: ${{ needs.ghcr_build.outputs.tags }}
  78. permissions:
  79. contents: read
  80. packages: write
  81. strategy:
  82. matrix:
  83. image: ['openhands']
  84. platform: ['amd64', 'arm64']
  85. steps:
  86. - name: Checkout code
  87. uses: actions/checkout@v4
  88. - name: Login to GHCR
  89. uses: docker/login-action@v3
  90. with:
  91. registry: ghcr.io
  92. username: ${{ github.repository_owner }}
  93. password: ${{ secrets.GITHUB_TOKEN }}
  94. - name: Download Docker images
  95. uses: actions/download-artifact@v4
  96. with:
  97. name: ${{ matrix.image }}_image_${{ matrix.platform }}
  98. path: /tmp/${{ matrix.image }}_${{ steps.capture-tags.outputs.tags }}_${{ matrix.platform }}.tar
  99. - name: Load images and push to registry
  100. run: |
  101. mv /tmp/${{ matrix.platform }}/${{ matrix.image }}_${{ steps.capture-tags.outputs.tags }}_${{ matrix.platform }}.tar .
  102. loaded_image=$(docker load -i ${{ matrix.image }}_${{ steps.capture-tags.outputs.tags }}_${{ matrix.platform }}.tar | grep "Loaded image:" | head -n 1 | awk '{print $3}')
  103. echo "loaded image = $loaded_image"
  104. tags=$(echo ${tags} | tr ' ' '\n')
  105. image_name=$(echo "ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}" | tr '[:upper:]' '[:lower:]')
  106. echo "image name = $image_name"
  107. for tag in $tags; do
  108. echo "tag = $tag"
  109. docker tag $loaded_image $image_name:${tag}_${{ matrix.platform }}
  110. docker push $image_name:${tag}_${{ matrix.platform }}
  111. done
  112. # Creates and pushes the OpenHands and sandbox Docker image manifests
  113. create_manifest:
  114. runs-on: ubuntu-latest
  115. needs: [ghcr_build, ghcr_push]
  116. if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') || (github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main')
  117. env:
  118. tags: ${{ needs.ghcr_build.outputs.tags }}
  119. strategy:
  120. matrix:
  121. image: ['openhands']
  122. permissions:
  123. contents: read
  124. packages: write
  125. steps:
  126. - name: Checkout code
  127. uses: actions/checkout@v4
  128. - name: Login to GHCR
  129. uses: docker/login-action@v3
  130. with:
  131. registry: ghcr.io
  132. username: ${{ github.repository_owner }}
  133. password: ${{ secrets.GITHUB_TOKEN }}
  134. - name: Create and push multi-platform manifest
  135. run: |
  136. image_name=$(echo "ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}" | tr '[:upper:]' '[:lower:]')
  137. echo "image name = $image_name"
  138. tags=$(echo ${tags} | tr ' ' '\n')
  139. for tag in $tags; do
  140. echo 'tag = $tag'
  141. docker buildx imagetools create --tag $image_name:$tag \
  142. $image_name:${tag}_amd64 \
  143. $image_name:${tag}_arm64
  144. done