GiitHub Actions의 보고서에 변경된 항목만 테스트

12999 단어 GitHub Actionstech

중요한 추기


이 글의 주요 내용은 sparse checkkout,git diff를 통해 판정하는 것입니다. 저는 on입니다.push.paths의 존재를 몰라요. 이걸 사용하면 아래처럼 sparse checkkout을 사용하면 돼요.
# .github/workflows/foo-test.yaml
name: foo-test
on:
  push:
    paths: systems/foo/**
env:
  SPARSE_CHECKOUT_DIR: systems/foo
jobs:
  test:
    runs-on: Ubuntu-20.04
    steps:
      - name: sparse checkout
        run: |
          git clone --filter=blob:none --no-checkout --depth 1 --sparse https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git .
          git sparse-checkout init --cone
          git sparse-checkout add ${SPARSE_CHECKOUT_DIR}
          git checkout ${GITHUB_SHA}
      - run: echo write your tests
        working-directory: ./systems/foo
그래서 이 기사는 기본적으로 무용지물이지만, 열심히 쓸 테니 남겨두고...
보고서상으로는 이렇게 구성되어 있다.
systems/foo
systems/bar
전제는foo와bar는 큰 프로젝트로 서로 의존 관계가 없다는 것이다.
이때 간단하게push에서 두 가지 테스트를 진행하면 큰 낭비를 초래할 수 있다.예를 들어android와 웹은 같은 창고로 관리할 때다.
그리고 주변 환경이라면actions@checkout반복, 기본 설정 --depth 1 이지만, 문제는 github actions의 전송량이 무료 프레임워크를 초과했다는 것입니다.이것도 동시에 쓰러뜨려야 한다.

git sparse-checkout


git2.16 이후sparse-checkkout이 있으며 일부 지정한 창고만 선택할 수 있습니다.보통 까다로운 기능을 사용하지만 이번 목적을 위해 CI에서 사용하는 것이 가장 적합하다.
Git - git-sparse-checkout Documentation
그렇지만actions@checkoutsparse-checkkout 기능이 없습니다.
Options like sparse mode · Issue #172 · actions/checkout
따라서 참조https://github.com/actions/checkout/issues/172#issuecomment-689169138는 지정한 디렉터리만 clone합니다.
REPO="https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git"
git clone --filter=blob:none --no-checkout --depth 1  --sparse $REPO .
git sparse-checkout init --cone
git sparse-checkout add "folder1" "folder2/folder3"
git checkout ${GITHUB_SHA}
GITHUB_SHA는 GiitHub Action의 환경 변수이며 현재 제출된 해시입니다.

git diff --exit-code origin/main...${GITHUB_SHA} --relative ...


다음 코드는 현재 제출한 해시와origin/main(master)을 비교하고 차이가 있으면 exitcode1로 되돌려줍니다.이 때,relative를 지정해서 이 디렉터리의 diff를 보십시오.
git diff --exit-code origin/main...${GITHUB_SHA} --relative=systems/foo
이렇게 하면main에 비해 차이가 검출되기 때문에 테스트 여부를 결정한다.

jobs의 의존성과 반환값


github actions::set-output name=[key]:[value]에서 이 step의 값을 설정할 수 있습니다.
    step:
      - id: foo
        echo "::set-output name=x::1"
## これは ${{steps.foo.outputs.x}} として参照できる
그 밖에 GiitHub Actions는job 간의 의존 관계를 발표할 수도 있고 후속job의 의존원인outputs를 참조할 수도 있다.
GiitHub Actions에서 Job의 Output 값은 다음 Job에서 -notebook 참조
이전의 Giit를 조합해서 지정한 디렉터리에 변화가 있는지 적어서 전송하는 Job입니다.
env:
  SPARSE_CHECKOUT_DIR: systems/actionhub
jobs:
  check:
    runs-on: Ubuntu-20.04
    outputs:
      changed: ${{ steps.checkout.outputs.changed }}
    steps:
      - id: checkout
        name: sparse checkout
        run: |
          git clone --filter=blob:none --no-checkout --depth 1 --sparse https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git .
          git sparse-checkout init --cone
          git sparse-checkout add ${SPARSE_CHECKOUT_DIR}
          git checkout ${GITHUB_SHA}
          echo "::set-output name=changed::$(git diff --exit-code origin/main --relative=${SPARSE_CHECKOUT_DIR} > /dev/null || echo $?)"
  test:
    runs-on: Ubuntu-20.04
    needs: [check]
    if: needs.check.outputs.changed == '1'
    steps:
      # your tests
왜 기뻐할까? 소박한 steps 참조라면 if: steps.checkout.outputs.changed == '1'를 모든 steps에 써야 하고, 테스트 잡에 대해 한 번if: needs.check.outputs.changed == '1'만 판정하면 된다.

완성


# .github/workflows/foo-test.yaml
name: foo-test
on: [push]

env:
  SPARSE_CHECKOUT_DIR: systems/foo
jobs:
  check:
    runs-on: Ubuntu-20.04
    outputs:
      changed: ${{ steps.checkout.outputs.changed }}
    steps:
      - id: checkout
        name: sparse checkout
        run: |
          git clone --filter=blob:none --no-checkout --depth 1 --sparse https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git .
          git sparse-checkout init --cone
          git sparse-checkout add ${SPARSE_CHECKOUT_DIR}
          git checkout ${GITHUB_SHA}
          echo "::set-output name=changed::$(git diff --exit-code origin/main --relative=${SPARSE_CHECKOUT_DIR} > /dev/null || echo $?)"
  test:
    runs-on: Ubuntu-20.04
    needs: [check]
    if: needs.check.outputs.changed == '1'
    steps:
      - name: sparse checkout
        run: |
          git clone --filter=blob:none --no-checkout --depth 1 --sparse https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git .
          git sparse-checkout init --cone
          git sparse-checkout add ${SPARSE_CHECKOUT_DIR}
          git checkout ${GITHUB_SHA}
      - run: echo write your tests
        working-directory: ./systems/foo
솔직히 미묘한 느낌도 있어요.sparse checkkout 두 번 했으니까.나는 두 번을 해도if를 모두 가져가야 하며 요구에 따라 발생하는 사고는 매우 위험하다고 생각한다.그리고 복제하기 쉬워요.
창고에 있는script화를 하고 싶은데 checkkout 이전이어서 코드 자체가 존재하지 않아서 내연에 이 코드를 두 번 붙였어요.
아마actions@checkoutsparse-check을 지원하거나 누군가가 그것을 action화하면 됩니다.나머지는 여러분께 드리는 숙제로circleci-agent step halt 상당히 많은

좋은 웹페이지 즐겨찾기