name: Publish Images And Chart on: workflow_dispatch: push: branches: - main - master tags: - "v*" env: REGISTRY_HOST: ${{ vars.CLUSTER_GITEA_HOST }} REGISTRY_NAMESPACE: ${{ vars.CONTAINER_REGISTRY_NAMESPACE }} REGISTRY_PLAIN_HTTP: ${{ vars.CONTAINER_REGISTRY_INSECURE }} CHART_NAME: attune jobs: metadata: name: Resolve Publish Metadata runs-on: ubuntu-latest outputs: registry: ${{ steps.meta.outputs.registry }} namespace: ${{ steps.meta.outputs.namespace }} registry_plain_http: ${{ steps.meta.outputs.registry_plain_http }} image_tag: ${{ steps.meta.outputs.image_tag }} image_tags: ${{ steps.meta.outputs.image_tags }} chart_version: ${{ steps.meta.outputs.chart_version }} app_version: ${{ steps.meta.outputs.app_version }} release_channel: ${{ steps.meta.outputs.release_channel }} steps: - name: Resolve tags and registry paths id: meta shell: bash run: | set -euo pipefail registry="${REGISTRY_HOST}" namespace="${REGISTRY_NAMESPACE}" registry_plain_http_raw="${REGISTRY_PLAIN_HTTP:-}" registry_host_only="${registry%%:*}" registry_plain_http_default="false" if [ -z "$registry" ]; then echo "CLUSTER_GITEA_HOST app variable is required" exit 1 fi if [ -z "$namespace" ]; then namespace="${{ github.repository_owner }}" fi if printf '%s' "$registry_host_only" | grep -Eq '(^|[.])svc[.]cluster[.]local$'; then registry_plain_http_default="true" fi if [ -n "$registry_plain_http_raw" ]; then case "$(printf '%s' "$registry_plain_http_raw" | tr '[:upper:]' '[:lower:]')" in 1|true|yes|on) registry_plain_http="true" ;; 0|false|no|off) registry_plain_http="false" ;; *) echo "CONTAINER_REGISTRY_INSECURE must be a boolean when set" exit 1 ;; esac else registry_plain_http="$registry_plain_http_default" fi short_sha="$(printf '%s' "${{ github.sha }}" | cut -c1-12)" ref_type="${{ github.ref_type }}" ref_name="${{ github.ref_name }}" if [ "$ref_type" = "tag" ] && printf '%s' "$ref_name" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+([-.].*)?$'; then version="${ref_name#v}" image_tags="${version},latest,sha-${short_sha}" chart_version="$version" release_channel="release" else version="sha-${short_sha}" image_tags="edge,sha-${short_sha}" chart_version="0.0.0-dev.${{ github.run_number }}" release_channel="edge" fi { echo "registry=$registry" echo "namespace=$namespace" echo "registry_plain_http=$registry_plain_http" echo "image_tag=$version" echo "image_tags=$image_tags" echo "chart_version=$chart_version" echo "app_version=$version" echo "release_channel=$release_channel" } >> "$GITHUB_OUTPUT" publish-images: name: Publish ${{ matrix.image.name }} runs-on: ubuntu-latest needs: metadata strategy: fail-fast: false matrix: image: - name: api repository: attune-api dockerfile: docker/Dockerfile.optimized context: . target: "" build_args: | SERVICE=api - name: executor repository: attune-executor dockerfile: docker/Dockerfile.optimized context: . target: "" build_args: | SERVICE=executor - name: notifier repository: attune-notifier dockerfile: docker/Dockerfile.optimized context: . target: "" build_args: | SERVICE=notifier - name: sensor repository: attune-sensor dockerfile: docker/Dockerfile.sensor.optimized context: . target: sensor-full build_args: "" - name: worker repository: attune-worker dockerfile: docker/Dockerfile.worker.optimized context: . target: worker-full build_args: "" - name: web repository: attune-web dockerfile: docker/Dockerfile.web context: . target: "" build_args: "" - name: migrations repository: attune-migrations dockerfile: docker/Dockerfile.migrations context: . target: "" build_args: "" - name: init-user repository: attune-init-user dockerfile: docker/Dockerfile.init-user context: . target: "" build_args: "" - name: init-packs repository: attune-init-packs dockerfile: docker/Dockerfile.init-packs context: . target: "" build_args: "" steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Docker Buildx if: needs.metadata.outputs.registry_plain_http != 'true' uses: docker/setup-buildx-action@v3 - name: Setup Docker Buildx For Plain HTTP Registry if: needs.metadata.outputs.registry_plain_http == 'true' uses: docker/setup-buildx-action@v3 with: buildkitd-config-inline: | [registry."${{ needs.metadata.outputs.registry }}"] http = true insecure = true - name: Log in to Gitea OCI registry shell: bash env: REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} GITHUB_TOKEN_FALLBACK: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail username="${REGISTRY_USERNAME:-${{ github.actor }}}" password="${REGISTRY_PASSWORD:-${GITHUB_TOKEN_FALLBACK:-}}" registry="${{ needs.metadata.outputs.registry }}" if [ -z "$password" ]; then echo "Set CONTAINER_REGISTRY_PASSWORD or enable GITHUB_TOKEN package writes" exit 1 fi if [ "${{ needs.metadata.outputs.registry_plain_http }}" = "true" ]; then registry="http://${registry}" fi printf '%s' "$password" | docker login "$registry" \ --username "$username" \ --password-stdin - name: Prepare image tags id: tags shell: bash run: | set -euo pipefail image_ref_base="${{ needs.metadata.outputs.registry }}/${{ needs.metadata.outputs.namespace }}/${{ matrix.image.repository }}" tag_lines="" IFS=',' read -ra tags <<< "${{ needs.metadata.outputs.image_tags }}" for tag in "${tags[@]}"; do tag_lines="${tag_lines}${image_ref_base}:${tag}"$'\n' done printf 'tags<> "$GITHUB_OUTPUT" - name: Build and push image shell: bash run: | set -euo pipefail build_cmd=( docker buildx build "${{ matrix.image.context }}" --file "${{ matrix.image.dockerfile }}" --push ) if [ -n "${{ matrix.image.target }}" ]; then build_cmd+=(--target "${{ matrix.image.target }}") fi while IFS= read -r tag; do [ -n "$tag" ] && build_cmd+=(--tag "$tag") done <<< "${{ steps.tags.outputs.tags }}" while IFS= read -r build_arg; do [ -n "$build_arg" ] && build_cmd+=(--build-arg "$build_arg") done <<< "${{ matrix.image.build_args }}" "${build_cmd[@]}" publish-chart: name: Publish Helm Chart runs-on: ubuntu-latest needs: - metadata - publish-images steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Helm uses: azure/setup-helm@v4 - name: Log in to Gitea OCI registry shell: bash env: REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} GITHUB_TOKEN_FALLBACK: ${{ secrets.GITHUB_TOKEN }} run: | set -euo pipefail registry_username="${REGISTRY_USERNAME:-${{ github.actor }}}" registry_password="${REGISTRY_PASSWORD:-${GITHUB_TOKEN_FALLBACK:-}}" login_args=() if [ -z "$registry_password" ]; then echo "Set CONTAINER_REGISTRY_PASSWORD or enable GITHUB_TOKEN package writes" exit 1 fi if [ "${{ needs.metadata.outputs.registry_plain_http }}" = "true" ]; then login_args+=(--plain-http) fi printf '%s' "$registry_password" | helm registry login "${{ needs.metadata.outputs.registry }}" \ --username "$registry_username" \ "${login_args[@]}" \ --password-stdin - name: Lint chart run: | helm lint charts/attune - name: Package chart run: | mkdir -p dist helm package charts/attune \ --destination dist \ --version "${{ needs.metadata.outputs.chart_version }}" \ --app-version "${{ needs.metadata.outputs.app_version }}" - name: Push chart to OCI registry run: | push_args=() if [ "${{ needs.metadata.outputs.registry_plain_http }}" = "true" ]; then push_args+=(--plain-http) fi helm push "dist/${CHART_NAME}-${{ needs.metadata.outputs.chart_version }}.tgz" \ "oci://${{ needs.metadata.outputs.registry }}/${{ needs.metadata.outputs.namespace }}/helm" \ "${push_args[@]}"