diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 432aee9938..835e853a1e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,6 +30,10 @@ jobs: TAG=$(cat esphome/const.py | sed -n -E "s/^__version__\s+=\s+\"(.+)\"$/\1/p") today="$(date --utc '+%Y%m%d')" TAG="${TAG}${today}" + BRANCH=${GITHUB_REF#refs/heads/} + if [[ "$BRANCH" != "dev" ]]; then + TAG="${TAG}-${BRANCH}" + fi fi echo "tag=${TAG}" >> $GITHUB_OUTPUT # yamllint enable rule:line-length @@ -57,7 +61,7 @@ jobs: run: twine upload dist/* deploy-docker: - name: Build and publish docker containers + name: Build and publish ESPHome ${{ matrix.image.title}} if: github.repository == 'esphome/esphome' permissions: contents: read @@ -66,8 +70,19 @@ jobs: needs: [init] strategy: matrix: - arch: [amd64, armv7, aarch64] - build_type: ["ha-addon", "docker", "lint"] + image: + - title: "ha-addon" + suffix: "hassio" + target: "hassio" + baseimg: "hassio" + - title: "docker" + suffix: "" + target: "docker" + baseimg: "docker" + - title: "lint" + suffix: "lint" + target: "lint" + baseimg: "docker" steps: - uses: actions/checkout@v3 - name: Set up Python @@ -92,54 +107,29 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Generate short tags + id: tags + run: | + docker/generate_tags.py \ + --tag "${{ needs.init.outputs.tag }}" \ + --suffix "${{ matrix.image.suffix }}" + - name: Build and push - run: | - docker/build.py \ - --tag "${{ needs.init.outputs.tag }}" \ - --arch "${{ matrix.arch }}" \ - --build-type "${{ matrix.build_type }}" \ - build \ - --push - - deploy-docker-manifest: - if: github.repository == 'esphome/esphome' - permissions: - contents: read - packages: write - runs-on: ubuntu-latest - needs: [init, deploy-docker] - strategy: - matrix: - build_type: ["ha-addon", "docker", "lint"] - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 + uses: docker/build-push-action@v3 with: - python-version: "3.9" - - name: Enable experimental manifest support - run: | - mkdir -p ~/.docker - echo "{\"experimental\": \"enabled\"}" > ~/.docker/config.json - - - name: Log in to docker hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Log in to the GitHub container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Run manifest - run: | - docker/build.py \ - --tag "${{ needs.init.outputs.tag }}" \ - --build-type "${{ matrix.build_type }}" \ - manifest + context: . + file: ./docker/Dockerfile + platforms: linux/amd64,linux/arm/v7,linux/arm64 + target: ${{ matrix.image.target }} + push: true + # yamllint disable rule:line-length + cache-from: type=registry,ref=ghcr.io/${{ steps.tags.output.image }}:cache-${{ steps.tags.outputs.channel }} + cache-to: type=registry,ref=ghcr.io/${{ steps.tags.output.image }}:cache-${{ steps.tags.outputs.channel }},mode=max + # yamllint enable rule:line-length + tags: ${{ steps.tags.outputs.tags }} + build-args: | + BASEIMGTYPE=${{ matrix.image.baseimg }} + BUILD_VERSION=${{ needs.init.outputs.tag }} deploy-ha-addon-repo: if: github.repository == 'esphome/esphome' && github.event_name == 'release' diff --git a/docker/generate_tags.py b/docker/generate_tags.py new file mode 100755 index 0000000000..71d0735526 --- /dev/null +++ b/docker/generate_tags.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import re +import os +import argparse +import json + +CHANNEL_DEV = "dev" +CHANNEL_BETA = "beta" +CHANNEL_RELEASE = "release" + +parser = argparse.ArgumentParser() +parser.add_argument( + "--tag", + type=str, + required=True, + help="The main docker tag to push to. If a version number also adds latest and/or beta tag", +) +parser.add_argument( + "--suffix", + type=str, + required=True, + help="The suffix of the tag.", +) + + +def main(): + args = parser.parse_args() + + # detect channel from tag + match = re.match(r"^(\d+\.\d+)(?:\.\d+)?(b\d+)?$", args.tag) + major_minor_version = None + if match is None: + channel = CHANNEL_DEV + elif match.group(2) is None: + major_minor_version = match.group(1) + channel = CHANNEL_RELEASE + else: + channel = CHANNEL_BETA + + tags_to_push = [args.tag] + if channel == CHANNEL_DEV: + tags_to_push.append("dev") + elif channel == CHANNEL_BETA: + tags_to_push.append("beta") + elif channel == CHANNEL_RELEASE: + # Additionally push to beta + tags_to_push.append("beta") + tags_to_push.append("latest") + + if major_minor_version: + tags_to_push.append("stable") + tags_to_push.append(major_minor_version) + + suffix = f"-{args.suffix}" if args.suffix else "" + + with open(os.environ["GITHUB_OUTPUT"], "w") as f: + print(f"channel={channel}", file=f) + print(f"image=esphome/esphome{suffix}", file=f) + full_tags = [] + + for tag in tags_to_push: + full_tags += [f"ghcr.io/esphome/esphome{suffix}:{tag}"] + full_tags += [f"esphome/esphome{suffix}:{tag}"] + print(f"tags={','.join(full_tags)}", file=f) + + +if __name__ == "__main__": + main()