Skip to content

Commit

Permalink
feat: rewrite release system to support multiple images per commit
Browse files Browse the repository at this point in the history
A critical limitation of the first design was the assumption that there would only be one Docker build per commit.  As such, software packages were often only refreshed when Zephyr was upgraded.

This new design opens the door to better CI practices.  It allows regular rebuilds of the Docker images irrespective of version control.  This is critical for incorporating the latest security fixes and bug patches as soon as possible.

Maintainers are still required to trigger stable releases (via tags), but this can be revisited in the future if further automation is necessary.

PR: zmkfirmware#50
  • Loading branch information
innovaker committed May 22, 2021
1 parent 3a6b0f0 commit 4dc263c
Showing 1 changed file with 70 additions and 6 deletions.
76 changes: 70 additions & 6 deletions .github/workflows/containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,29 @@ jobs:
versions: ${{ steps.definitions.outputs.versions }}
major-minor: ${{ steps.definitions.outputs.major-minor }}
latest: ${{ steps.definitions.outputs.latest }}
release-trigger: ${{ steps.definitions.outputs.release-trigger }}
steps:
- name: Definitions
id: definitions
env:
SHA: ${{ github.sha }}
RUN_ID: ${{ github.run_id }}
ZEPHYR_VERSION: ${{ env.zephyr-version }}
ZEPHYR_SDK_VERSION: ${{ env.zephyr-sdk-version }}
run: |
BRANCH=${GITHUB_REF#refs/heads/}
BRANCH=${BRANCH//[^A-Za-z0-9_.-]/_} # Substitutes invalid Docker tag characters
CANDIDATE=${SHA}
CANDIDATE=${BRANCH}-${ZEPHYR_VERSION}-${ZEPHYR_SDK_VERSION}-$(date +%Y%m%d%H%M%S)-${SHA}-${RUN_ID}
VERSIONS=${ZEPHYR_VERSION}-${ZEPHYR_SDK_VERSION}
MAJOR=$(echo ${ZEPHYR_VERSION} | cut -d'.' -f 1)
MINOR=$(echo ${ZEPHYR_VERSION} | cut -d'.' -f 2)
MAJOR_MINOR=${MAJOR}.${MINOR}
LATEST=${MAJOR_MINOR}
RELEASE_TRIGGER=${ZEPHYR_VERSION}-${ZEPHYR_SDK_VERSION}
echo ::set-output name=branch::${BRANCH}
echo ::set-output name=candidate::${CANDIDATE}
echo ::set-output name=versions::${VERSIONS}
echo ::set-output name=major-minor::${MAJOR_MINOR}
echo ::set-output name=latest::${LATEST}
echo ::set-output name=release-trigger::${RELEASE_TRIGGER}
candidates:
needs:
- architectures
Expand Down Expand Up @@ -221,11 +219,77 @@ jobs:
shell: bash
run: |
docker image push docker.io/${{ env.docker-hub-namespace }}/${{ steps.repository.outputs.name }}:${{ needs.tags.outputs.candidate }}
release-trigger:
if: ${{ startsWith(github.ref, 'refs/tags') }}
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.match.outputs.tag }}
branch: ${{ steps.match.outputs.branch }}
zephyr-version: ${{ steps.match.outputs.zephyr-version }}
zephyr-version-major: ${{ steps.match.outputs.zephyr-version-major }}
zephyr-version-minor: ${{ steps.match.outputs.zephyr-version-minor }}
zephyr-version-patch: ${{ steps.match.outputs.zephyr-version-patch }}
zephyr-sdk-version: ${{ steps.match.outputs.zephyr-sdk-version }}
zephyr-sdk-version-major: ${{ steps.match.outputs.zephyr-sdk-version-major }}
zephyr-sdk-version-minor: ${{ steps.match.outputs.zephyr-sdk-version-minor }}
zephyr-sdk-version-patch: ${{ steps.match.outputs.zephyr-sdk-version-patch }}
datetime: ${{ steps.match.outputs.datetime }}
date: ${{ steps.match.outputs.date }}
year: ${{ steps.match.outputs.year }}
month: ${{ steps.match.outputs.month }}
day: ${{ steps.match.outputs.day }}
time: ${{ steps.match.outputs.time }}
hour: ${{ steps.match.outputs.hour }}
minute: ${{ steps.match.outputs.minute }}
second: ${{ steps.match.outputs.second }}
sha: ${{ steps.match.outputs.sha }}
run-id: ${{ steps.match.outputs.run-id }}
steps:
- name: Is tag a release trigger?
id: match
run: |
TAG=${GITHUB_REF#refs/tags/}
PATTERN="^(.+?)-(([0-9]+)\.([0-9]+)\.([0-9]+))-(([0-9]+)\.([0-9]+)\.([0-9]+))-((([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]))(([01]?[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])))-([0-9a-fA-F]+)-([0-9]+)$"
if [[ "${TAG}" =~ $PATTERN ]]; then
echo ::set-output name=tag::${TAG}
echo ::set-output name=branch::${BASH_REMATCH[1]}
echo ::set-output name=zephyr-version::${BASH_REMATCH[2]}
echo ::set-output name=zephyr-version-major::${BASH_REMATCH[3]}
echo ::set-output name=zephyr-version-minor::${BASH_REMATCH[4]}
echo ::set-output name=zephyr-version-patch::${BASH_REMATCH[5]}
echo ::set-output name=zephyr-sdk-version::${BASH_REMATCH[6]}
echo ::set-output name=zephyr-sdk-version-major::${BASH_REMATCH[7]}
echo ::set-output name=zephyr-sdk-version-minor::${BASH_REMATCH[8]}
echo ::set-output name=zephyr-sdk-version-patch::${BASH_REMATCH[9]}
echo ::set-output name=datetime::${BASH_REMATCH[10]}
echo ::set-output name=date::${BASH_REMATCH[11]}
echo ::set-output name=year::${BASH_REMATCH[12]}
echo ::set-output name=month::${BASH_REMATCH[13]}
echo ::set-output name=day::${BASH_REMATCH[14]}
echo ::set-output name=time::${BASH_REMATCH[15]}
echo ::set-output name=hour::${BASH_REMATCH[16]}
echo ::set-output name=minute::${BASH_REMATCH[17]}
echo ::set-output name=second::${BASH_REMATCH[18]}
SHA=${BASH_REMATCH[19]}
echo ::set-output name=sha::${SHA}
echo ::set-output name=run-id::${BASH_REMATCH[20]}
if [ "${{ github.sha }}" != "${SHA}" ]; then
echo "Git hashes do not match!"
echo "Docker tag: ${SHA}"
echo "Git tag: ${{ github.sha }}"
exit 1
fi
else
echo "Tag not recognised, ignoring ..."
fi
continue-on-error: true
releases:
needs:
- architectures
- tags
if: ${{ github.ref == format('refs/tags/{0}', needs.tags.outputs.release-trigger) }}
- release-trigger
if: ${{ needs.release-trigger.outputs.sha != null }}
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down Expand Up @@ -253,7 +317,7 @@ jobs:
GHCRNS: ${{ env.ghcr-namespace }}
TARGET: ${{ matrix.target }}
ARCHITECTURE: ${{ matrix.architecture }}
CANDIDATE: ${{ needs.tags.outputs.candidate }}
CANDIDATE: ${{ needs.release-trigger.outputs.tag }}
VERSIONS: ${{ needs.tags.outputs.versions }}
LATEST: ${{ needs.tags.outputs.latest }}
run: |
Expand Down

0 comments on commit 4dc263c

Please sign in to comment.