name: Container build on: push: branches: - 'main' - 'stable' - 'beta' - 'release/**' tags: - 'v*' pull_request: branches: - '**' paths: - '.github/workflows/dev_container.yml' - 'Tools/setup/ubuntu.sh' - 'Tools/setup/requirements.txt' - 'Tools/setup/Dockerfile' - 'Tools/setup/docker-entrypoint.sh' workflow_dispatch: inputs: px4_version: description: 'Container tag (e.g. v1.16.0)' required: true type: string deploy_to_registry: description: 'Whether to push built images to the registry' required: false type: boolean default: false concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: setup: name: Set Tags and Variables permissions: contents: read runs-on: [runs-on,"runner=1cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] outputs: px4_version: ${{ steps.px4_version.outputs.px4_version }} meta_tags: ${{ steps.meta.outputs.tags }} meta_labels: ${{ steps.meta.outputs.labels }} steps: - uses: runs-on/action@v1 - uses: actions/checkout@v4 with: fetch-tags: true submodules: false fetch-depth: 0 # If manual dispatch, take the user‐provided input - name: Set PX4 Tag Version id: px4_version run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then echo "px4_version=${{ github.event.inputs.px4_version }}" >> $GITHUB_OUTPUT else echo "px4_version=$(git describe --tags --match 'v[0-9]*')" >> $GITHUB_OUTPUT fi - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v5 with: images: | ghcr.io/PX4/px4-dev px4io/px4-dev tags: | type=raw,enable=true,value=${{ steps.px4_version.outputs.px4_version }},priority=1000 build: name: Build Container (${{ matrix.arch }}) permissions: contents: read packages: write needs: setup strategy: matrix: include: - platform: linux/arm64 arch: arm64 runner: arm64 - platform: linux/amd64 arch: amd64 runner: x64 runs-on: [runs-on,"runner=4cpu-linux-${{ matrix.runner }}","image=ubuntu24-full-${{ matrix.runner }}","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] steps: - uses: runs-on/action@v1 - uses: actions/checkout@v4 with: fetch-tags: true submodules: false fetch-depth: 0 - name: Login to Docker Hub uses: docker/login-action@v3 if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to GitHub Container Registry uses: docker/login-action@v3 if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: driver: docker-container platforms: ${{ matrix.platform }} - name: Build and Load Container Image uses: docker/build-push-action@v6 id: docker with: context: Tools/setup tags: | ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-${{ matrix.arch }} px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-${{ matrix.arch }} labels: ${{ needs.setup.outputs.meta_labels }} platforms: ${{ matrix.platform }} load: false push: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} provenance: false cache-from: type=gha,scope=${{ matrix.arch }} cache-to: type=gha,mode=max,scope=${{ matrix.arch }} deploy: name: Deploy To Registry permissions: contents: read packages: write runs-on: [runs-on,"runner=4cpu-linux-x64","image=ubuntu24-full-x64","run-id=${{ github.run_id }}",extras=s3-cache,spot=false] needs: [build, setup] if: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }} steps: - uses: runs-on/action@v1 - uses: actions/checkout@v4 with: fetch-tags: true submodules: false fetch-depth: 0 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Verify Images Exist Before Creating Manifest run: | docker manifest inspect px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 || echo "⚠️ Warning: No ARM64 image found!" docker manifest inspect px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 || echo "⚠️ Warning: No AMD64 image found!" docker manifest inspect ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 || echo "⚠️ Warning: No ARM64 image found!" docker manifest inspect ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 || echo "⚠️ Warning: No AMD64 image found!" - name: Create and Push Multi-Arch Manifest for Docker Hub run: | docker manifest create px4io/px4-dev:${{ needs.setup.outputs.px4_version }} \ --amend px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 \ --amend px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 docker manifest annotate px4io/px4-dev:${{ needs.setup.outputs.px4_version }} px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 --arch arm64 docker manifest annotate px4io/px4-dev:${{ needs.setup.outputs.px4_version }} px4io/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 --arch amd64 docker manifest push px4io/px4-dev:${{ needs.setup.outputs.px4_version }} - name: Create and Push Multi-Arch Manifest for GHCR run: | docker manifest create ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }} \ --amend ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 \ --amend ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 docker manifest annotate ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }} ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-arm64 --arch arm64 docker manifest annotate ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }} ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}-amd64 --arch amd64 docker manifest push ghcr.io/px4/px4-dev:${{ needs.setup.outputs.px4_version }}