Compare commits

2 Commits

Author SHA1 Message Date
cb91ecc9f6 feat(build.py): implement gitea workflow trigger
Some checks failed
Building alt images / build-process (push) Has been cancelled
2025-06-23 23:35:14 +03:00
761fda61c1 feat(.gitea/workflow): implement build of arbitrary images 2025-06-23 23:29:59 +03:00
3 changed files with 100 additions and 89 deletions

View File

@ -2,7 +2,7 @@ name: Building alt images
on: on:
push: push:
tags: tags:
- '*' - '**'
jobs: jobs:
build-process: build-process:
@ -58,37 +58,43 @@ jobs:
EV: ${{ toJson(gitea.event) }} EV: ${{ toJson(gitea.event) }}
run: | run: |
branch="$(echo $EV | jq '.ref' -r | sed "s|refs/tags/||g" | cut -d '_' -f 1)" branch="$(echo $EV | jq '.ref' -r | sed "s|refs/tags/||g" | cut -d '_' -f 1)"
echo $EV | jq '.ref' -r | sed "s|refs/tags/|BRANCH=|g" | cut -d '_' -f 1 echo "BRANCH=$branch"
echo $EV | jq '.ref' -r | sed "s|refs/tags/|BRANCH=|g" | cut -d '_' -f 1 >> ${GITHUB_ENV}
rest="$(echo $EV | jq '.ref' -r | sed "s|refs/tags/|BRANCH=|g" | cut -d '_' -f 1-)"
rest="$(echo $EV | jq '.ref' -r | sed "s|refs/tags/||g" | cut -d '_' -f 2-)"
IFS='_' read -ra parts <<< "$rest" IFS='_' read -ra parts <<< "$rest"
images=() images=()
declare -A versions declare -A versions
for part in "${parts[@]}"; do for part in "${parts[@]}"; do
image="${part%@*}" if [[ "$part" == *@* ]]; then
version="${part#*@}" image="${part%@*}"
images+=("$image") version="${part#*@}"
versions["$image"]="$version" images+=("$image")
versions["$image"]="$version"
else
image="$part"
images+=("$image")
fi
done done
image_args="${images[*]}" image_args="${images[*]}"
# Build JSON for package-versions
package_versions="{" package_versions="{"
for i in "${!images[@]}"; do first=1
img="${images[$i]}" for image in "${!versions[@]}"; do
ver="${versions[$img]}" [[ $first -eq 0 ]] && package_versions+=","
sep=$([[ $i -lt $((${#images[@]} - 1)) ]] && echo "," || echo "") package_versions+="\"$image\": \"${versions[$image]}\""
package_versions+="\"$img\": \"$ver\"$sep" first=0
done done
package_versions+="}" package_versions+="}"
echo "IMAGES=$image_args" >> $GITEA_OUTPUT echo "IMAGES=$image_args"
echo "PACKAGE_VERSIONS=$package_versions" >> $GITEA_OUTPUT echo "PACKAGE_VERSIONS=$package_versions"
echo "BRANCH=$branch" >> ${GITHUB_ENV}
echo "IMAGES=$image_args" >> $GITHUB_ENV
echo "PACKAGE_VERSIONS=$package_versions" >> $GITHUB_ENV
- name: Change vendor label for c10f - name: Change vendor label for c10f
if: ${{ contains(github.ref_name, 'c10f') }} if: ${{ contains(github.ref_name, 'c10f') }}
run: | run: |
@ -98,16 +104,18 @@ jobs:
sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||: sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||:
env: env:
ORG: ${{ env.ORG }} ORG: ${{ env.ORG }}
- name: Get test for image
run: |
if test -f ${{ gitea.workspace }}/org/$IM/test; then testscript=$(cat ${{ gitea.workspace }}/org/$IM/test); else testscript=""; fi
echo "TEST=$testscript" >> ${GITHUB_ENV}
env:
IM: ${{ env.IMAGE }}
BR: ${{ env.BRANCH }}
- name: Run building script - name: Run building script
id: build-script id: build-script
run: | run: |
echo "${{ gitea.workspace }}/build.py \
--log-level debug \
--skip-stages push \
--branch $BRANCH \
--registry gitea.basealt.ru/alt \
--arches amd64 \
-i $IMAGES \
--package-versions \"$PACKAGE_VERSIONS\""
${{ gitea.workspace }}/build.py \ ${{ gitea.workspace }}/build.py \
--log-level debug \ --log-level debug \
--skip-stages push \ --skip-stages push \
@ -136,8 +144,8 @@ jobs:
# IM: ${{ env.IMAGE }} # IM: ${{ env.IMAGE }}
- name: Delete event tag - name: Delete event tag
run: | run: |
tagname=$(echo $EV | jq '.ref' -r | sed "s/refs\/tags\///g") tagname=$(echo $EV | jq '.ref' -r | sed "s|refs/tags/||g")
curl -X 'DELETE' "$URL/api/v1/repos/$REPO/image-forge/tags/$tagname?token=$T" -H 'accept: application/json' -s curl -X 'DELETE' "$URL/api/v1/repos/$REPO/image-forge/tags/$tagname" -H "Authorization: token $T" -H 'accept: application/json' -s
echo "tag $tagname is deleted" echo "tag $tagname is deleted"
env: env:
T: ${{ secrets.TOKEN }} T: ${{ secrets.TOKEN }}
@ -145,55 +153,3 @@ jobs:
URL: ${{ gitea.server_url }} URL: ${{ gitea.server_url }}
REPO: ${{ env.REPO }} REPO: ${{ env.REPO }}
EV: ${{ toJson(gitea.event) }} EV: ${{ toJson(gitea.event) }}
test-process:
needs: build-process
if: ${{ needs.build-process.outputs.buildres == 'success' }}
runs-on: alt-sisyphus
steps:
- name: Update apt
uses: https://gitea.basealt.ru/actions/init-alt-env@v1
- name: Install requires
run: |
echo "apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl"
apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl
- name: Run test
id: test-script
if: ${{ needs.build-process.outputs.test != '' }}
continue-on-error: true
run: |
imname=$(echo "$IM" | cut -d "/" -f2)
if [[ "$IM" == *"k8s"* ]]; then echo "skip tests for k8s images"; else podman run --rm --entrypoint="/bin/sh" $URL/$REPO/$BR/$imname:latest -c "$TEST"; fi
env:
IM: ${{ needs.build-process.outputs.image }}
BR: ${{ needs.build-process.outputs.branch }}
URL: ${{ needs.build-process.outputs.url }}
REPO: ${{ needs.build-process.outputs.repo }}
TEST: ${{ needs.build-process.outputs.test }}
- name: Run special test
id: special-test
if: ${{ needs.build-process.outputs.test == '' }}
continue-on-error: true
run: |
imname=$(echo "$IM" | cut -d "/" -f2)
if [[ $IM = 'alt/distroless-true' ]]; then podman run --rm $URL/$REPO/$BR/$imname:latest true; fi
if [[ $IM = 'alt/distroless-gotop' ]]; then podman run --rm $URL/$REPO/$BR/$imname:latest --version; fi
env:
IM: ${{ needs.build-process.outputs.image }}
BR: ${{ needs.build-process.outputs.branch }}
URL: ${{ needs.build-process.outputs.url }}
REPO: ${{ needs.build-process.outputs.repo }}
- name: Send notification if test crashed
if: ${{ steps.test-script.outcome == 'failure' || steps.special-test.outcome == 'failure' }}
run: |
issueid=1
errors=$(cat errors.log)
body="Testing image $IM finish with some errors."
curl -X 'POST' "$URL/api/v1/repos/$REPO/image-forge/issues/$issueid/comments?token=$T" -H 'accept: application/json' -H 'Content-Type: application/json' -d "{ \"body\": \"$body\" }" -s
echo "notification about test error is sent to issue $issueid"
env:
T: ${{ secrets.TOKEN }}
BR: ${{ needs.build-process.outputs.branch }}
URL: ${{ gitea.server_url }}
REPO: ${{ needs.build-process.outputs.repo }}
IM: ${{ needs.build-process.outputs.image }}

View File

@ -21,7 +21,7 @@ jobs:
echo "URL=$repourl" >> ${GITHUB_ENV} echo "URL=$repourl" >> ${GITHUB_ENV}
echo "URL=$repourl" echo "URL=$repourl"
reponame=$(echo $GR | cut -d '/' -f 1) reponame=$(echo $GR | cut -d '/' -f 1)
echo "REPO=$reponame" >> ${GITHUB_ENV} echo "REPO=$reponame" >> ${GITHUB_ENV}
echo "REPO=$reponame" echo "REPO=$reponame"
env: env:
GU: ${{ gitea.server_url }} GU: ${{ gitea.server_url }}
@ -29,7 +29,7 @@ jobs:
- name: Set repo for c10f2 (Temporary) - name: Set repo for c10f2 (Temporary)
if: ${{ contains(github.ref_name, 'c10f2') }} if: ${{ contains(github.ref_name, 'c10f2') }}
run: | run: |
echo "event tag=${{ github.ref_name }}" echo "event tag=${{ github.ref_name }}"
echo "10.4.0.3 update.altsp.su" >> /etc/hosts echo "10.4.0.3 update.altsp.su" >> /etc/hosts
echo "cat /etc/hosts" echo "cat /etc/hosts"
cat /etc/hosts cat /etc/hosts
@ -46,14 +46,14 @@ jobs:
- name: Login podman gitea - name: Login podman gitea
run: | run: |
echo "podman login ${{ env.URL }}" echo "podman login ${{ env.URL }}"
podman login --username $P_USER --password $P_PASS ${{ env.URL }} podman login --username $P_USER --password $P_PASS ${{ env.URL }}
env: env:
P_USER: ${{ secrets.PODMAN_USER }} P_USER: ${{ secrets.PODMAN_USER }}
P_PASS: ${{ secrets.PODMAN_PASS }} P_PASS: ${{ secrets.PODMAN_PASS }}
- name: Check files in the repository - name: Check files in the repository
run: | run: |
ls -a ${{ gitea.workspace }} ls -a ${{ gitea.workspace }}
- name: Parse target branch and tag from events context, save to env - name: Parse target branch and tag from events context, save to env
env: env:
EV: ${{ toJson(gitea.event) }} EV: ${{ toJson(gitea.event) }}
run: | run: |
@ -75,7 +75,7 @@ jobs:
sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/Dockerfile.template ||: sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/Dockerfile.template ||:
echo "sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||:" echo "sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||:"
sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||: sed -i 's/ALT Linux Team/BaseALT LLC/g' ${{ gitea.workspace }}/org/$ORG/*/distroless.toml ||:
env: env:
ORG: ${{ env.ORG }} ORG: ${{ env.ORG }}
- name: Get test for image - name: Get test for image
run: | run: |
@ -90,7 +90,7 @@ jobs:
if [[ "$IM" == *"k8s"* ]]; then k8sarg="--package-versions {\"$IM\":\"$VER\"}"; else k8sarg=""; fi if [[ "$IM" == *"k8s"* ]]; then k8sarg="--package-versions {\"$IM\":\"$VER\"}"; else k8sarg=""; fi
if [[ "$BR" == "sisyphus" ]]; then arches="--arches amd64 386 arm64 loong64"; else arches="--arches amd64 386 arm64"; fi if [[ "$BR" == "sisyphus" ]]; then arches="--arches amd64 386 arm64 loong64"; else arches="--arches amd64 386 arm64"; fi
echo "build.py -i $IM -b $BR $arches $k8sarg" echo "build.py -i $IM -b $BR $arches $k8sarg"
${{ gitea.workspace }}/build.py -i $IM -b $BR $arches --latest $BR --log-level debug --registry gitea.basealt.ru/alt $k8sarg ${{ gitea.workspace }}/build.py -i $IM -b $BR $arches --latest $BR --log-level debug --registry gitea.basealt.ru/alt $k8sarg
env: env:
IM: ${{ env.IMAGE }} IM: ${{ env.IMAGE }}
VER: ${{ env.VER }} VER: ${{ env.VER }}
@ -103,7 +103,7 @@ jobs:
issueid=1 issueid=1
body="Building image $IM finish with some errors." body="Building image $IM finish with some errors."
curl -X 'POST' "$URL/api/v1/repos/$REPO/image-forge/issues/$issueid/comments?token=$T" -H 'accept: application/json' -H 'Content-Type: application/json' -d "{ \"body\": \"$body\" }" -s curl -X 'POST' "$URL/api/v1/repos/$REPO/image-forge/issues/$issueid/comments?token=$T" -H 'accept: application/json' -H 'Content-Type: application/json' -d "{ \"body\": \"$body\" }" -s
echo "notification about test error is sent to issue $issueid" echo "notification about test error is sent to issue $issueid"
env: env:
T: ${{ secrets.TOKEN }} T: ${{ secrets.TOKEN }}
BR: ${{ env.BRANCH }} BR: ${{ env.BRANCH }}
@ -131,7 +131,7 @@ jobs:
- name: Install requires - name: Install requires
run: | run: |
echo "apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl" echo "apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl"
apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl apt-get install -y python3-module-tomli python3-module-jinja2 podman buildah curl
- name: Run test - name: Run test
id: test-script id: test-script
if: ${{ needs.build-process.outputs.test != '' }} if: ${{ needs.build-process.outputs.test != '' }}
@ -140,9 +140,9 @@ jobs:
imname=$(echo "$IM" | cut -d "/" -f2) imname=$(echo "$IM" | cut -d "/" -f2)
if [[ "$IM" == *"k8s"* ]]; then echo "skip tests for k8s images"; else podman run --rm --entrypoint="/bin/sh" $URL/$REPO/$BR/$imname:latest -c "$TEST"; fi if [[ "$IM" == *"k8s"* ]]; then echo "skip tests for k8s images"; else podman run --rm --entrypoint="/bin/sh" $URL/$REPO/$BR/$imname:latest -c "$TEST"; fi
env: env:
IM: ${{ needs.build-process.outputs.image }} IM: ${{ needs.build-process.outputs.image }}
BR: ${{ needs.build-process.outputs.branch }} BR: ${{ needs.build-process.outputs.branch }}
URL: ${{ needs.build-process.outputs.url }} URL: ${{ needs.build-process.outputs.url }}
REPO: ${{ needs.build-process.outputs.repo }} REPO: ${{ needs.build-process.outputs.repo }}
TEST: ${{ needs.build-process.outputs.test }} TEST: ${{ needs.build-process.outputs.test }}
- name: Run special test - name: Run special test
@ -165,7 +165,7 @@ jobs:
errors=$(cat errors.log) errors=$(cat errors.log)
body="Testing image $IM finish with some errors." body="Testing image $IM finish with some errors."
curl -X 'POST' "$URL/api/v1/repos/$REPO/image-forge/issues/$issueid/comments?token=$T" -H 'accept: application/json' -H 'Content-Type: application/json' -d "{ \"body\": \"$body\" }" -s curl -X 'POST' "$URL/api/v1/repos/$REPO/image-forge/issues/$issueid/comments?token=$T" -H 'accept: application/json' -H 'Content-Type: application/json' -d "{ \"body\": \"$body\" }" -s
echo "notification about test error is sent to issue $issueid" echo "notification about test error is sent to issue $issueid"
env: env:
T: ${{ secrets.TOKEN }} T: ${{ secrets.TOKEN }}
BR: ${{ needs.build-process.outputs.branch }} BR: ${{ needs.build-process.outputs.branch }}

View File

@ -4,12 +4,14 @@ import argparse
import functools import functools
import json import json
import logging import logging
import os
import re import re
import subprocess import subprocess
import textwrap import textwrap
from datetime import datetime from datetime import datetime
from dataclasses import dataclass from dataclasses import dataclass
from graphlib import TopologicalSorter from graphlib import TopologicalSorter
from http import HTTPStatus
from pathlib import Path from pathlib import Path
from typing import Optional, Union from typing import Optional, Union
@ -948,6 +950,23 @@ def parse_args():
choices=log_levels, choices=log_levels,
help="log messages above specified level", help="log messages above specified level",
) )
parser.add_argument(
"--run-workflow",
action="store_true",
help="run gitea workflow to build oci images",
)
parser.add_argument(
"--workflow-repo",
default="stepchenkoas/image-forge",
help="path to gitea repository where to activate workflow",
)
parser.add_argument(
"--workflow-branch",
default="master",
help="branch in gitea repository where to activate workflow",
)
args = parser.parse_args() args = parser.parse_args()
args.stages = set(args.stages) - set(args.skip_stages) args.stages = set(args.stages) - set(args.skip_stages)
@ -971,6 +990,42 @@ def main():
logger.info("PKG_VERSIONS=%s", PKG_VERSIONS) logger.info("PKG_VERSIONS=%s", PKG_VERSIONS)
if args.run_workflow:
gitea_token = os.environ.get("GITEA_TOKEN")
if gitea_token is None:
raise RuntimeError("Gitea authorization token is not provided through the environment variable GITEA_TOKEN")
api_url = f"https://gitea.basealt.ru/api/v1/repos/{args.workflow_repo}/tags"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": f"token {gitea_token}",
}
tag_name = list(args.branches)[0]
for image in args.images:
tag_name += "_" + image
if PKG_VERSIONS is not None:
if (version := PKG_VERSIONS.get(image)) is not None:
tag_name += "@" + version
logger.debug("tag_name=\"%s\"", tag_name)
json = {
"message": "workflow trigger",
"target": args.workflow_branch,
"tag_name": tag_name,
}
response = requests.post(api_url, json=json, headers=headers)
if response.status_code != HTTPStatus.CREATED:
print(f"{response.status_code=}")
raise RuntimeError(
f"failed to run workflow: {response.text!r}"
)
return
arches = args.arches arches = args.arches
images_info = ImagesInfo() images_info = ImagesInfo()
tags = Tags(args.tags, args.latest) tags = Tags(args.tags, args.latest)