首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GitHub工作流:当仅在主版上构建时,我如何附加标记一个Docker映像?

GitHub工作流:当仅在主版上构建时,我如何附加标记一个Docker映像?
EN

Stack Overflow用户
提问于 2022-06-18 22:21:22
回答 1查看 1.1K关注 0票数 0

我已经挖了一段时间了,还想不出怎么做到这一点。

我现在拥有的:端到端,我有两个工作流。一个监视Pi孔的新释放,另一个在新提交发生时构建一个码头映像。

目标:使用GitHub工作流,只有在提交到master分支时,我才希望构建一个带有masterlatest和提交上的每个标记(通常是版本标记)的单独的Docker映像。这样,无论我提交到master还是我的Pi孔监控器工作流进行提交,适当的停靠者图像标记都将只从单个构建运行中发布。

用例1: --我向master提交了一个更新,并更改了Dockerfile。结果应该是使用masterlatest标记发布一个新的坞映像。应该使用单个停靠器图像,以便标记的SHA匹配。当前Pi孔版本的图像应该保持不变。

这是目前的工作!我得到了一个坞构建运行,它发布了masterlatest下的映像。

用例2:我的Pi孔监控器工作流检测新的Pi孔发布。结果应该是一个新的对接图像发布了三个标签:masterlatest和Pi孔释放标签(例如pihole-v5.10)。应该使用单个停靠器图像,以便标记的SHA匹配。

这目前不起作用。这会触发我的工作流程两次。那么,两个码头建设运行。latest会更新两次(以先完成者为准)。master和版本标记(pihole-v*.*)有不同的SHAs。

工作流#1: Pi孔监控器

代码语言:javascript
复制
name: Pi-hole Monitor
on:
  schedule:
    - cron:  '0 8 * * *'
  workflow_dispatch:
jobs:
  check-pihole-version:
    runs-on: ubuntu-latest
    steps:
      # https://github.com/actions/checkout
      - name: Checkout repository
        uses: actions/checkout@v2
        # https://stackoverflow.com/questions/67550727/push-event-doesnt-trigger-workflow-on-push-paths-github-actions
        with:
          token: ${{ secrets.BUILD_AUTOMATION_TOKEN }}

      - name: Fetch latest release version of Pi-hole
        id: pi-hole_ver
        run: |
          curl -sL https://api.github.com/repos/pi-hole/pi-hole/releases/latest | \
          jq -r ".tag_name" > pihole-latest.txt
          echo ::set-output name=pihole-latest::$(cat pihole-latest.txt)

      - name: Check for modified files
        id: git-check
        run: echo ::set-output name=modified::$([ -z "`git status --porcelain`" ] && echo "false" || echo "true")

      - name: Commit latest release version
        if: steps.git-check.outputs.modified == 'true'
        run: |
          git config --global user.name 'Hossy'
          git config --global user.email 'Hossy@users.noreply.github.com'
          git commit -am "New Pi-hole release ${{ steps.pi-hole_ver.outputs.pihole-latest }}"
          git tag -am "Pi-hole ${{ steps.pi-hole_ver.outputs.pihole-latest }}" pihole-${{ steps.pi-hole_ver.outputs.pihole-latest }}
          git push origin pihole-${{ steps.pi-hole_ver.outputs.pihole-latest }}
          git push

工作流#2: Docker

代码语言:javascript
复制
name: Publish Docker Image

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
  schedule:
    - cron: '37 8 1,15 * *'
  push:
    branches: [ master ]
    tags: [ 'pihole-**' ]
    paths-ignore: [ '.github/**' ]
  pull_request:
    branches: [ master ]
  workflow_dispatch:

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as <account>/<repo>
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:

    runs-on: ubuntu-latest
    permissions:
      packages: write

    steps:
      # Login against a Docker registry except on PR
      # https://github.com/docker/login-action
      - name: Log into registry ${{ env.REGISTRY }}
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2.0.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      # Extract metadata (tags, labels) for Docker
      # https://github.com/docker/metadata-action
      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@v4.0.1
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          # set latest tag for master branch
          tags: |
            type=schedule
            type=ref,event=branch
            type=ref,event=tag
            type=ref,event=pr
            type=raw,value=latest,enable={{is_default_branch}}

      # Build and push Docker image with Buildx (don't push on PR)
      # https://github.com/docker/build-push-action
      - name: Build and push Docker image
        uses: docker/build-push-action@v3.0.0
        with:
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

我已经看过并仍在修补的其他事情可能会有所帮助:

EN

回答 1

Stack Overflow用户

发布于 2022-06-19 20:05:01

在贴出这个问题后,我继续挖掘,并找到了解决方案。我不认为这是一个很好的解决方案,但它实现了目标。

我还想补充一点,最严重的是,GitHub API是严重缺乏的。但我离题了。为好东西干杯!

我最后做的是:

  1. 使用GitHub API调用GET /repos/:owner/:repo/tags,检索存储库中存在的每个标记。这是我找到的唯一返回标记提交SHA的API调用。所有其他人都继续返回标记本身的对象SHA (对我来说没用)。

示例输出(JSON数组):

代码语言:javascript
复制
[
    {
        "name": "pihole-v5.10",
        "zipball_url": "https://api.github.com/repos/Hossy/pihole/zipball/refs/tags/pihole-v5.10",
        "tarball_url": "https://api.github.com/repos/Hossy/pihole/tarball/refs/tags/pihole-v5.10",
        "commit": {
            "sha": "e696d33d0dca3df5157cbc8558cc303cec027851",
            "url": "https://api.github.com/repos/Hossy/pihole/commits/e696d33d0dca3df5157cbc8558cc303cec027851"
        },
        "node_id": "MDM6UmVmMjc4NDM1ODg3OnJlZnMvdGFncy9waWhvbGUtdjUuMTA="
    }
]
  1. jq解析JSON输出并筛选到具有与工作流提交SHA匹配的commit的标记。
  2. 执行一些字符串操作,将来自docker/metadata-action和GitHub API (jq)的标记合并起来,为docker/build-push-action构建一个标记的超集。

我的新码头建设者工作流:

代码语言:javascript
复制
name: Publish Docker Image

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
  schedule:
    - cron: '37 8 1,15 * *'
  push:
    branches: [ master ]
    #tags: [ 'pihole-**' ]
    paths-ignore: [ '.github/**' ]
  pull_request:
    branches: [ master ]
  # workflow_dispatch:

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as <account>/<repo>
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:

    runs-on: ubuntu-latest
    permissions:
      # contents: read
      packages: write

    steps:
      # Login against a Docker registry except on PR
      # https://github.com/docker/login-action
      - name: Log into registry ${{ env.REGISTRY }}
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2.0.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      # Extract metadata (tags, labels) for Docker
      # https://github.com/docker/metadata-action
      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@v4.0.1
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          # set latest tag for master branch
          tags: |
            type=schedule
            type=ref,event=branch
            type=ref,event=tag
            type=ref,event=pr
            type=raw,value=latest,enable={{is_default_branch}}

      # Retrieve all repository tags from the GitHub API using undocumented API call to get all tags
      # https://github.com/actions/github-script
      - name: Get all tags
        id: all-tags
        uses: actions/github-script@v6
        with:
          script: |
            const path = "/repos/" + "${{ github.repository }}" + "/tags"
            const parameters = "{'" + "${{ github.repository_owner }}" + "', '" + "${{ github.repository }}" + "'}"
            return github.rest.git.getTag(path,parameters)
      
      # Prepare JSON output for Unix command line
      # https://github.com/mad9000/actions-find-and-replace-string
      - name: Format jq result
        id: formatted-jq
        uses: mad9000/actions-find-and-replace-string@2
        with:
          source: ${{ steps.all-tags.outputs.result }}
          find: "'"
          replace: "\\\'"

      # Parse Github API output and search for tags only matching the current commit SHA 
      - name: Search all tags for commit
        id: tag-results
        run: echo ::set-output name=tags::"$( echo '${{ steps.formatted-jq.outputs.value }}' | jq -r ".data | .[] | select( .commit.sha == \"${{ github.sha }}\" ) | .name" )"
      
      # Merge the tag lists from docker/metadata-action and GitHub API
      - name: Build tag list
        id: tag-list
        run: |
          echo ::set-output name=tags::"$(
            echo -n "${{ steps.meta.outputs.tags }}" | tr '\n' ','
            for r in `echo "${{ steps.tag-results.outputs.tags }}" | tr '\n' ' '`; do echo -n ,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$r | tr '[:upper:]' '[:lower:]'; done
          )"

      # Build and push Docker image with Buildx (don't push on PR)
      # https://github.com/docker/build-push-action
      - name: Build and push Docker image
        uses: docker/build-push-action@v3.0.0
        with:
          # context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.tag-list.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72673143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档