Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build

on:
workflow_call:
inputs:
version:
description: 'Version to build'
required: true
type: string
outputs:
build_run_id:
description: 'Run ID of the build workflow'
value: ${{ jobs.build.outputs.run_id }}

jobs:
build:
runs-on: ubuntu-latest
outputs:
run_id: ${{ steps.build-meta.outputs.run_id }}
steps:
- uses: actions/checkout@v4

- name: Export build run id
id: build-meta
run: echo "run_id=${{ github.run_id }}" >> $GITHUB_OUTPUT

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
APP_VERSION=${{ inputs.version }}
tags: |
liveboxmonitor:${{ inputs.version }}
outputs: type=oci,dest=./image.tar
push: false

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: image-${{ inputs.version }}
path: ./image.tar
retention-days: 1
83 changes: 83 additions & 0 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Release Workflow

on:
schedule:
- cron: "0 2 * * *" # Run at 2:00 AM every day
pull_request:
branches:
- main
workflow_dispatch:
inputs:
release:
description: 'Release new version if true'
required: false
default: false
type: boolean

permissions:
contents: write
packages: write
actions: read

jobs:
extract-version:
runs-on: ubuntu-latest
name: Extract Version
outputs:
versions_differ: ${{ steps.compare_versions.outputs.versions_differ }}
lbm_version: ${{ steps.get_lbm_version.outputs.lbm_version }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get LiveboxMonitor current version
id: get_lbm_version
run: |
LBM_VERSION=$(curl -s https://api.github.com/repos/p-dor/LiveboxMonitor/releases/latest | jq -r '.tag_name')
echo "Current LiveboxMonitor version is $LBM_VERSION"
echo "lbm_version=$LBM_VERSION" >> $GITHUB_OUTPUT
- name: Get latest tag
id: get_latest_tag
run: |
LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1))
LATEST_VERSION="${LATEST_TAG#v}"
echo "Latest tag is $LATEST_TAG (version $LATEST_VERSION)"
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT
- name: Compare versions
id: compare_versions
run: |
echo "Comparing LiveboxMonitor version ${{ steps.get_lbm_version.outputs.lbm_version }} with latest tag version ${{ steps.get_latest_tag.outputs.latest_version }}"
if [ "${{ steps.get_lbm_version.outputs.lbm_version }}" != "${{ steps.get_latest_tag.outputs.latest_version }}" ]; then
echo "versions_differ=true" >> $GITHUB_OUTPUT
else
echo "versions_differ=false" >> $GITHUB_OUTPUT
fi

build:
uses: ./.github/workflows/build.yaml
if: needs.extract-version.outputs.versions_differ == 'true' ||
github.event_name == 'pull_request'
needs: extract-version
with:
version: ${{ needs.extract-version.outputs.lbm_version }}

test:
uses: ./.github/workflows/test.yaml
if: needs.extract-version.outputs.versions_differ == 'true' ||
github.event_name == 'pull_request'
needs: [build, extract-version]
with:
version: ${{ needs.extract-version.outputs.lbm_version }}
build_run_id: ${{ needs.build.outputs.build_run_id }}

release:
uses: ./.github/workflows/publish.yaml
if: github.event_name != 'pull_request' &&
(github.event_name == 'workflow_dispatch' && github.event.inputs.release == 'true') &&
needs.extract-version.outputs.versions_differ == 'true'
needs: [build, test, extract-version]
with:
version: ${{ needs.extract-version.outputs.lbm_version }}
build_run_id: ${{ needs.build.outputs.build_run_id }}
secrets: inherit
110 changes: 110 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Publish

on:
workflow_call:
inputs:
version:
description: 'Version to publish'
required: true
type: string
build_run_id:
description: 'Run ID of the build workflow'
required: true
type: string

env:
REGISTRY_GHCR: ghcr.io
REGISTRY_DOCKER: docker.io

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: image-${{ inputs.version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
run-id: ${{ inputs.build_run_id }}
path: .

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_GHCR }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_DOCKER }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Load image from artifact
run: |
docker load --input ./image.tar

- name: Push to GitHub Container Registry
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
${{ env.REGISTRY_GHCR }}/${{ github.repository_owner }}/liveboxmonitor:${{ inputs.version }}
${{ env.REGISTRY_GHCR }}/${{ github.repository_owner }}/liveboxmonitor:latest

- name: Push to Docker Hub
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
${{ env.REGISTRY_DOCKER }}/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:${{ inputs.version }}
${{ env.REGISTRY_DOCKER }}/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:latest

- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.version.outputs.tag }}
release_name: Release ${{ steps.version.outputs.version }}
body: |
# LiveboxMonitor Container v${{ steps.version.outputs.version }}

Built from: [${{ github.sha }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }})

## Images Available at :

### GitHub Container Registry

- `/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:${{ steps.version.outputs.version }}`
- `/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:latest`

### Docker Hub

- `/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:${{ steps.version.outputs.version }}`
- `/${{ secrets.DOCKER_USERNAME }}/liveboxmonitor:latest`

## Upstream Project
- **LiveboxMonitor**: https://github.com/p-dor/LiveboxMonitor
draft: false
prerelease: false
105 changes: 105 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Test

on:
workflow_call:
inputs:
version:
description: "Version to test"
required: true
type: string
build_run_id:
description: "Run ID of the build workflow"
required: true
type: string

jobs:
download-and-test:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read

strategy:
fail-fast: false
matrix:
platform: [amd64, arm64]

steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: image-${{ inputs.version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
run-id: ${{ inputs.build_run_id }}
path: ./artifact

- name: Show downloaded files
run: ls -lah ./artifact

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Install skopeo
run: |
sudo apt-get update
sudo apt-get install -y skopeo

- name: Import image for ${{ matrix.platform }} into Docker
run: |
set -euo pipefail
IMAGE_TAG="liveboxmonitor:${{ inputs.version }}"

# Extract the linux/${{ matrix.platform }} variant from the OCI archive
skopeo copy \
--override-os linux \
--override-arch ${{ matrix.platform }} \
oci-archive:./artifact/image.tar \
docker-daemon:${IMAGE_TAG}

docker image inspect "${IMAGE_TAG}" >/dev/null
echo "Imported ${IMAGE_TAG} for arch ${{ matrix.platform }}"

- name: Run healthcheck
shell: bash
run: |
set -euo pipefail
IMAGE_TAG="liveboxmonitor:${{ inputs.version }}"
NAME="liveboxmonitor-test-${{ matrix.platform }}"

# Verify that the image has a HEALTHCHECK (otherwise the test can never pass)
HAS_HEALTH=$(docker image inspect -f '{{if .Config.Healthcheck}}yes{{else}}no{{end}}' "${IMAGE_TAG}")
if [ "${HAS_HEALTH}" != "yes" ]; then
echo "No HEALTHCHECK defined in the image -> failing test."
exit 1
fi

docker run -d --rm --platform "linux/${{ matrix.platform }}" --name "${NAME}" "${IMAGE_TAG}"
echo "Started container: ${NAME}"

MAX_ATTEMPTS=20
for ATTEMPT in $(seq 1 ${MAX_ATTEMPTS}); do
STATUS=$(docker inspect -f '{{.State.Status}}' "${NAME}" || true)
HEALTH=$(docker inspect -f '{{.State.Health.Status}}' "${NAME}" 2>/dev/null || echo "unknown")

echo "Attempt ${ATTEMPT}/${MAX_ATTEMPTS}: status=${STATUS} health=${HEALTH}"

if [ "${STATUS}" != "running" ]; then
echo "Container exited. Logs:"
docker logs "${NAME}" || true
exit 1
fi

if [ "${HEALTH}" = "healthy" ]; then
echo "Container is healthy!"
docker stop "${NAME}"
exit 0
fi

sleep 5
done

echo "Timeout waiting for healthy. Logs:"
docker logs "${NAME}" || true
docker stop "${NAME}" || true
exit 1