diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index ffa7d59..509f1d4 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -10,15 +10,17 @@ jobs: runs-on: almalinux-8 container: image: git.unkin.net/unkin/almalinux8-actionsdind:latest - options: --privileged + options: "--privileged --volume /etc/pki/tls/vault:/etc/pki/tls/vault:ro" steps: - name: Checkout code uses: actions/checkout@v3 - name: Build Packages + env: + VAULT_ROLE_ID: ${{ secrets.RPMBUILDER_VAULT_ROLEID }} run: | - make all + make all DISTRO=el/8 - name: Show RPMs run: | @@ -34,15 +36,17 @@ jobs: runs-on: almalinux-8 container: image: git.unkin.net/unkin/almalinux9-actionsdind:latest - options: --privileged + options: "--privileged --volume /etc/pki/tls/vault:/etc/pki/tls/vault:ro" steps: - name: Checkout code uses: actions/checkout@v3 - name: Build Packages + env: + VAULT_ROLE_ID: ${{ secrets.RPMBUILDER_VAULT_ROLEID }} run: | - make all + make all DISTRO=el/9 - name: Show RPMs run: | diff --git a/.gitignore b/.gitignore index 1521c8b..be49a96 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ dist +env +.claude diff --git a/rpms/helmfile/Dockerfile b/Dockerfile similarity index 81% rename from rpms/helmfile/Dockerfile rename to Dockerfile index 539afe6..acacc0f 100644 --- a/rpms/helmfile/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest +ARG BASE_IMAGE=git.unkin.net/unkin/almalinux9-rpmbuilder:latest +FROM ${BASE_IMAGE} # Create output directory for RPMs RUN mkdir -p /app/dist diff --git a/Makefile b/Makefile index 7e634a1..ff02ba4 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,85 @@ # Variables ROOT_DIR := $(PWD) -RPMS_DIR := $(ROOT_DIR)/rpms -REPO_OPTIONS := --disablerepo=* --enablerepo=unkin +BUILD_TOOL := $(ROOT_DIR)/tools/build +DISTRO ?= el/9 # Default to el/9 if not specified -# Automatically find all package/version directories -PACKAGES := $(shell find $(RPMS_DIR) -mindepth 2 -maxdepth 2 -type d | sed "s|$(RPMS_DIR)/||" | grep -Ev '(scripts|/resources)') +# Automatically find all packages with metadata.yaml +PACKAGES := $(shell find $(ROOT_DIR)/rpms -mindepth 1 -maxdepth 1 -type d -exec test -f {}/metadata.yaml \; -print | xargs -n1 basename | sort) -# Default target to build all packages and versions -.PHONY: all list cache build clean -all: cache $(PACKAGES) +# Default target to build all packages +.PHONY: all list build clean +all: build-all +# List all available packages list: - @echo "Builds:" + @echo "Available packages:" @for package in $(PACKAGES); do \ - echo " '$$package'"; \ + echo " $$package"; \ done -cache: - echo "Refreshing DNF cache..." && \ - dnf clean all && \ - dnf makecache +# Build all packages using Python tool +build-all: + @echo "Building all packages using Python tooling for distro $(DISTRO)..." + $(BUILD_TOOL) --all --distro $(DISTRO) -# Build specific package/version +# Build specific package using Python tool .PHONY: $(PACKAGES) $(PACKAGES): - @PACKAGE_NAME=$(shell echo $(@) | cut -d/ -f1) && \ - PACKAGE_VERSION=$(shell echo $(@) | cut -d/ -f2) && \ - echo "Starting build $$PACKAGE_NAME/$$PACKAGE_VERSION" && \ - $(MAKE) build PACKAGE_NAME=$$PACKAGE_NAME PACKAGE_VERSION=$$PACKAGE_VERSION + @echo "Building package: $@ for distro $(DISTRO)" + $(BUILD_TOOL) --package $@ --distro $(DISTRO) -# Build target +# Build specific package with version/release override build: - @mkdir -p $(ROOT_DIR)/dist/$(PACKAGE_NAME)/ - @cd $(RPMS_DIR)/$(PACKAGE_NAME) && \ - export PACKAGE_RELEASE=$$(cat $(PACKAGE_VERSION)/release) && \ - export PACKAGE_FULL_NAME=$(PACKAGE_NAME)-$(PACKAGE_VERSION)-$$PACKAGE_RELEASE && \ - echo "Checking repos for $$PACKAGE_FULL_NAME" && \ - if dnf info $$PACKAGE_FULL_NAME $(REPO_OPTIONS) > /dev/null 2>&1; then \ - echo "Skipping build for $(PACKAGE_NAME) version $(PACKAGE_VERSION) (already exists in the repository)"; \ - else \ - echo "Building RPM for $(PACKAGE_NAME) version $(PACKAGE_VERSION)"; \ - docker build \ - --build-arg PACKAGE_VERSION=$(PACKAGE_VERSION) \ - --build-arg PACKAGE_RELEASE=$${PACKAGE_RELEASE} \ - -t $$(echo $(PACKAGE_NAME)-builder \ - | tr '[:upper:]' '[:lower:]') . && \ - docker create --name $(PACKAGE_NAME)-$(PACKAGE_VERSION)-builder \ - $$(echo $(PACKAGE_NAME)-builder | tr '[:upper:]' '[:lower:]') && \ - docker start -a $(PACKAGE_NAME)-$(PACKAGE_VERSION)-builder && \ - docker cp $(PACKAGE_NAME)-$(PACKAGE_VERSION)-builder:/app/dist/. $(ROOT_DIR)/dist/$(PACKAGE_NAME)/ && \ - docker rm $(PACKAGE_NAME)-$(PACKAGE_VERSION)-builder; \ - fi + @if [ -z "$(PACKAGE_NAME)" ]; then \ + echo "Error: PACKAGE_NAME not specified"; \ + echo "Usage: make build PACKAGE_NAME=package [PACKAGE_VERSION=version] [PACKAGE_RELEASE=release]"; \ + exit 1; \ + fi + @if [ -n "$(PACKAGE_VERSION)" ] && [ -n "$(PACKAGE_RELEASE)" ]; then \ + echo "Building $(PACKAGE_NAME) with explicit version $(PACKAGE_VERSION)-$(PACKAGE_RELEASE) for distro $(DISTRO)"; \ + $(BUILD_TOOL) --package $(PACKAGE_NAME) --version $(PACKAGE_VERSION) --release $(PACKAGE_RELEASE) --distro $(DISTRO); \ + else \ + echo "Building $(PACKAGE_NAME) using metadata.yaml for distro $(DISTRO)"; \ + $(BUILD_TOOL) --package $(PACKAGE_NAME) --distro $(DISTRO); \ + fi + +# Dry run - show what would be built without building +dry-run: + @echo "Dry run - showing what would be built for distro $(DISTRO):" + $(BUILD_TOOL) --all --distro $(DISTRO) --dry-run # Clean target clean: @echo "Cleaning build artifacts..." rm -rf $(ROOT_DIR)/dist + +# Update packages from GitHub releases +update: + @echo "Checking for package updates from GitHub releases..." + $(ROOT_DIR)/tools/update-gh --all + +# Update specific package from GitHub +update-%: + @echo "Checking for updates for package: $*" + $(ROOT_DIR)/tools/update-gh --package $* + +# Help target +help: + @echo "Available targets:" + @echo " all - Build all packages (default)" + @echo " list - List all available packages" + @echo " build-all - Build all packages using Python tooling" + @echo " - Build specific package (e.g., 'make consul')" + @echo " build - Build with explicit PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_RELEASE" + @echo " dry-run - Show what would be built without building" + @echo " clean - Remove build artifacts" + @echo " update - Check all packages for GitHub release updates" + @echo " update- - Check specific package for GitHub release updates" + @echo " help - Show this help message" + @echo "" + @echo "Examples:" + @echo " make consul # Build consul using metadata.yaml" + @echo " make build PACKAGE_NAME=consul # Build consul using metadata.yaml" + @echo " make build PACKAGE_NAME=consul PACKAGE_VERSION=1.21.1 PACKAGE_RELEASE=1" + @echo " make update-consul # Check consul for GitHub updates" + @echo " make dry-run # Show what would be built" diff --git a/rpms/act_runner/0.2.12/release b/rpms/act_runner/0.2.12/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/act_runner/0.2.12/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/act_runner/Dockerfile b/rpms/act_runner/Dockerfile deleted file mode 100644 index f8cf216..0000000 --- a/rpms/act_runner/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy nfpm.yaml from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/bind_exporter/0.8.0/release b/rpms/bind_exporter/0.8.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/bind_exporter/0.8.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/bind_exporter/Dockerfile b/rpms/bind_exporter/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/bind_exporter/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/boilerplate/0.6.1/release b/rpms/boilerplate/0.6.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/boilerplate/0.6.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/boilerplate/Dockerfile b/rpms/boilerplate/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/boilerplate/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/cni-plugins/1.7.1/release b/rpms/cni-plugins/1.7.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/cni-plugins/1.7.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/cni-plugins/Dockerfile b/rpms/cni-plugins/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/cni-plugins/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/consul-cni/1.7.1/release b/rpms/consul-cni/1.7.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/consul-cni/1.7.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/consul-cni/Dockerfile b/rpms/consul-cni/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/consul-cni/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/consul/1.21.1/release b/rpms/consul/1.21.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/consul/1.21.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/consul/Dockerfile b/rpms/consul/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/consul/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/etcd/3.5.18/release b/rpms/etcd/3.5.18/release deleted file mode 100644 index 0cfbf08..0000000 --- a/rpms/etcd/3.5.18/release +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/rpms/etcd/Dockerfile b/rpms/etcd/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/etcd/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/exportarr/2.2.0/release b/rpms/exportarr/2.2.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/exportarr/2.2.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/exportarr/Dockerfile b/rpms/exportarr/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/exportarr/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/frr_exporter/1.8.0/release b/rpms/frr_exporter/1.8.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/frr_exporter/1.8.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/frr_exporter/Dockerfile b/rpms/frr_exporter/Dockerfile deleted file mode 100644 index f8cf216..0000000 --- a/rpms/frr_exporter/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy nfpm.yaml from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/g10k/0.9.10/release b/rpms/g10k/0.9.10/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/g10k/0.9.10/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/g10k/Dockerfile b/rpms/g10k/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/g10k/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/helmfile/1.1.7/release b/rpms/helmfile/1.1.7/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/helmfile/1.1.7/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/incus/6.10.1/release b/rpms/incus/6.10.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/incus/6.10.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/incus/Dockerfile b/rpms/incus/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/incus/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/jellyfin-ffmpeg-bin/7.1.1/release b/rpms/jellyfin-ffmpeg-bin/7.1.1/release deleted file mode 100644 index 00750ed..0000000 --- a/rpms/jellyfin-ffmpeg-bin/7.1.1/release +++ /dev/null @@ -1 +0,0 @@ -3 diff --git a/rpms/jellyfin-ffmpeg-bin/Dockerfile b/rpms/jellyfin-ffmpeg-bin/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/jellyfin-ffmpeg-bin/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/jellyfin-server/10.10.7/release b/rpms/jellyfin-server/10.10.7/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/jellyfin-server/10.10.7/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/jellyfin-server/Dockerfile b/rpms/jellyfin-server/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/jellyfin-server/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/jellyfin-web/10.10.7/release b/rpms/jellyfin-web/10.10.7/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/jellyfin-web/10.10.7/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/jellyfin-web/Dockerfile b/rpms/jellyfin-web/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/jellyfin-web/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/jsonnet-language-server/0.16.0/release b/rpms/jsonnet-language-server/0.16.0/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/jsonnet-language-server/0.16.0/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/jsonnet-language-server/Dockerfile b/rpms/jsonnet-language-server/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/jsonnet-language-server/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/jsonnet-lint/0.21.0/release b/rpms/jsonnet-lint/0.21.0/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/jsonnet-lint/0.21.0/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/jsonnet-lint/Dockerfile b/rpms/jsonnet-lint/Dockerfile deleted file mode 100644 index f7d01bb..0000000 --- a/rpms/jsonnet-lint/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Start with the AlmaLinux 9 base image -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/jsonnet-lint/metadata.yaml b/rpms/jsonnet-lint/metadata.yaml new file mode 100644 index 0000000..931e6c9 --- /dev/null +++ b/rpms/jsonnet-lint/metadata.yaml @@ -0,0 +1,9 @@ +name: jsonnet-lint +release: 1 +version: 0.21.0 +build: +- distro: el/8 + image: git.unkin.net/unkin/almalinux8-rpmbuilder:latest +- distro: el/9 + image: git.unkin.net/unkin/almalinux9-rpmbuilder:latest +github: google/go-jsonnet \ No newline at end of file diff --git a/rpms/jsonnet/0.21.0/release b/rpms/jsonnet/0.21.0/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/jsonnet/0.21.0/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/jsonnet/Dockerfile b/rpms/jsonnet/Dockerfile deleted file mode 100644 index f7d01bb..0000000 --- a/rpms/jsonnet/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Start with the AlmaLinux 9 base image -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/jsonnet/metadata.yaml b/rpms/jsonnet/metadata.yaml new file mode 100644 index 0000000..32d465e --- /dev/null +++ b/rpms/jsonnet/metadata.yaml @@ -0,0 +1,9 @@ +name: jsonnet +release: 1 +version: 0.21.0 +build: +- distro: el/8 + image: git.unkin.net/unkin/almalinux8-rpmbuilder:latest +- distro: el/9 + image: git.unkin.net/unkin/almalinux9-rpmbuilder:latest +github: google/go-jsonnet \ No newline at end of file diff --git a/rpms/libfoundationdb/7.3.71/release b/rpms/libfoundationdb/7.3.71/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/libfoundationdb/7.3.71/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/libfoundationdb/Dockerfile b/rpms/libfoundationdb/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/libfoundationdb/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/nfpm/2.41.1/release b/rpms/nfpm/2.41.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/nfpm/2.41.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/nfpm/Dockerfile b/rpms/nfpm/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/nfpm/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/node_exporter/1.9.1/release b/rpms/node_exporter/1.9.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/node_exporter/1.9.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/node_exporter/Dockerfile b/rpms/node_exporter/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/node_exporter/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/nomad-autoscaler/0.4.6/release b/rpms/nomad-autoscaler/0.4.6/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/nomad-autoscaler/0.4.6/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/nomad-autoscaler/Dockerfile b/rpms/nomad-autoscaler/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/nomad-autoscaler/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/nomad/1.10.1/release b/rpms/nomad/1.10.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/nomad/1.10.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/nomad/Dockerfile b/rpms/nomad/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/nomad/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/nzbget/25.0/release b/rpms/nzbget/25.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/nzbget/25.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/nzbget/Dockerfile b/rpms/nzbget/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/nzbget/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/nzbget_exporter/2025.08.03/release b/rpms/nzbget_exporter/2025.08.03/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/nzbget_exporter/2025.08.03/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/nzbget_exporter/Dockerfile b/rpms/nzbget_exporter/Dockerfile deleted file mode 100644 index f8cf216..0000000 --- a/rpms/nzbget_exporter/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy nfpm.yaml from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/openbao-plugin-secret-consul/0.1.0/release b/rpms/openbao-plugin-secret-consul/0.1.0/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/openbao-plugin-secret-consul/0.1.0/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/openbao-plugin-secret-consul/Dockerfile b/rpms/openbao-plugin-secret-consul/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/openbao-plugin-secret-consul/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/openbao-plugin-secret-nomad/0.1.4/release b/rpms/openbao-plugin-secret-nomad/0.1.4/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/openbao-plugin-secret-nomad/0.1.4/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/openbao-plugin-secret-nomad/Dockerfile b/rpms/openbao-plugin-secret-nomad/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/openbao-plugin-secret-nomad/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/openbao-plugins/1.0.0/release b/rpms/openbao-plugins/1.0.0/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/openbao-plugins/1.0.0/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/openbao-plugins/Dockerfile b/rpms/openbao-plugins/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/openbao-plugins/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/packer/1.13.1/release b/rpms/packer/1.13.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/packer/1.13.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/packer/Dockerfile b/rpms/packer/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/packer/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/pgbouncer_exporter/0.11.0/release b/rpms/pgbouncer_exporter/0.11.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/pgbouncer_exporter/0.11.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/pgbouncer_exporter/Dockerfile b/rpms/pgbouncer_exporter/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/pgbouncer_exporter/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/postgres_exporter/0.17.1/release b/rpms/postgres_exporter/0.17.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/postgres_exporter/0.17.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/postgres_exporter/Dockerfile b/rpms/postgres_exporter/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/postgres_exporter/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/puppet-initial/1.0.3/release b/rpms/puppet-initial/1.0.3/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/puppet-initial/1.0.3/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/puppet-initial/Dockerfile b/rpms/puppet-initial/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/puppet-initial/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/puppetdb_exporter/1.1.0/release b/rpms/puppetdb_exporter/1.1.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/puppetdb_exporter/1.1.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/puppetdb_exporter/Dockerfile b/rpms/puppetdb_exporter/Dockerfile deleted file mode 100644 index f8cf216..0000000 --- a/rpms/puppetdb_exporter/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy nfpm.yaml from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/ruff/0.8.1/release b/rpms/ruff/0.8.1/release deleted file mode 100644 index 1e8b314..0000000 --- a/rpms/ruff/0.8.1/release +++ /dev/null @@ -1 +0,0 @@ -6 diff --git a/rpms/ruff/Dockerfile b/rpms/ruff/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/ruff/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/stalwart-cli/0.13.4/release b/rpms/stalwart-cli/0.13.4/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/stalwart-cli/0.13.4/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/stalwart-cli/Dockerfile b/rpms/stalwart-cli/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/stalwart-cli/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/stalwart-foundationdb/0.13.4/release b/rpms/stalwart-foundationdb/0.13.4/release deleted file mode 100644 index 0cfbf08..0000000 --- a/rpms/stalwart-foundationdb/0.13.4/release +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/rpms/stalwart-foundationdb/Dockerfile b/rpms/stalwart-foundationdb/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/stalwart-foundationdb/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/stalwart/0.13.4/release b/rpms/stalwart/0.13.4/release deleted file mode 100644 index 0cfbf08..0000000 --- a/rpms/stalwart/0.13.4/release +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/rpms/stalwart/Dockerfile b/rpms/stalwart/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/stalwart/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/terraform/1.12.1/release b/rpms/terraform/1.12.1/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/terraform/1.12.1/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/terraform/1.5.0/release b/rpms/terraform/1.5.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/terraform/1.5.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/terraform/Dockerfile b/rpms/terraform/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/terraform/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/terragrunt/0.81.0/release b/rpms/terragrunt/0.81.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/terragrunt/0.81.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/terragrunt/0.90.0/release b/rpms/terragrunt/0.90.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/terragrunt/0.90.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/terragrunt/Dockerfile b/rpms/terragrunt/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/terragrunt/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/tflint/0.59.1/release b/rpms/tflint/0.59.1/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/tflint/0.59.1/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/tflint/Dockerfile b/rpms/tflint/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/tflint/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/unkin-ca-certificates/2025.07.13/release b/rpms/unkin-ca-certificates/2025.07.13/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/unkin-ca-certificates/2025.07.13/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/unkin-ca-certificates/Dockerfile b/rpms/unkin-ca-certificates/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/unkin-ca-certificates/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/unkin-undionly-kpxe/20250712.0.2/release b/rpms/unkin-undionly-kpxe/20250712.0.2/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/unkin-undionly-kpxe/20250712.0.2/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/unkin-undionly-kpxe/Dockerfile b/rpms/unkin-undionly-kpxe/Dockerfile deleted file mode 100644 index f8cf216..0000000 --- a/rpms/unkin-undionly-kpxe/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy nfpm.yaml from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/unrar/7.11.0/release b/rpms/unrar/7.11.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/unrar/7.11.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/unrar/Dockerfile b/rpms/unrar/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/unrar/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/uv/0.5.11/release b/rpms/uv/0.5.11/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/uv/0.5.11/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/uv/0.5.5/release b/rpms/uv/0.5.5/release deleted file mode 100644 index 0cfbf08..0000000 --- a/rpms/uv/0.5.5/release +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/rpms/uv/0.6.5/release b/rpms/uv/0.6.5/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/uv/0.6.5/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/uv/Dockerfile b/rpms/uv/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/uv/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vals/0.42.2/release b/rpms/vals/0.42.2/release deleted file mode 100644 index 56a6051..0000000 --- a/rpms/vals/0.42.2/release +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/rpms/vals/Dockerfile b/rpms/vals/Dockerfile deleted file mode 100644 index 539afe6..0000000 --- a/rpms/vals/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh \ No newline at end of file diff --git a/rpms/vault/1.19.5/release b/rpms/vault/1.19.5/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vault/1.19.5/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vault/Dockerfile b/rpms/vault/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/vault/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/victoria-logs/1.26.0/release b/rpms/victoria-logs/1.26.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/victoria-logs/1.26.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/victoria-logs/Dockerfile b/rpms/victoria-logs/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/victoria-logs/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vlutils/1.26.0/release b/rpms/vlutils/1.26.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vlutils/1.26.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vlutils/Dockerfile b/rpms/vlutils/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/vlutils/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vmagent/1.119.0/release b/rpms/vmagent/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vmagent/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vmagent/Dockerfile b/rpms/vmagent/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/vmagent/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vmalert/1.119.0/release b/rpms/vmalert/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vmalert/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vmalert/Dockerfile b/rpms/vmalert/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/vmalert/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vminsert/1.119.0/release b/rpms/vminsert/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vminsert/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vminsert/Dockerfile b/rpms/vminsert/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/vminsert/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vmselect/1.119.0/release b/rpms/vmselect/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vmselect/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vmselect/Dockerfile b/rpms/vmselect/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/vmselect/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vmstorage/1.119.0/release b/rpms/vmstorage/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vmstorage/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vmstorage/Dockerfile b/rpms/vmstorage/Dockerfile deleted file mode 100644 index 6d5dcec..0000000 --- a/rpms/vmstorage/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/rpms/vmutils/1.119.0/release b/rpms/vmutils/1.119.0/release deleted file mode 100644 index d00491f..0000000 --- a/rpms/vmutils/1.119.0/release +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/rpms/vmutils/Dockerfile b/rpms/vmutils/Dockerfile deleted file mode 100644 index 8d00407..0000000 --- a/rpms/vmutils/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM git.unkin.net/unkin/almalinux9-rpmbuilder:latest - -# Create output directory for RPMs -RUN mkdir -p /app/dist - -# Set working directory -WORKDIR /app - -ARG PACKAGE_RELEASE -ENV PACKAGE_RELEASE=${PACKAGE_RELEASE} -ARG PACKAGE_VERSION -ENV PACKAGE_VERSION=${PACKAGE_VERSION} - -# Copy resources from the context into the container -COPY resources /app/resources - -# Default command to build RPMs -CMD /app/resources/build.sh diff --git a/tools/build b/tools/build new file mode 100755 index 0000000..9c09214 --- /dev/null +++ b/tools/build @@ -0,0 +1,889 @@ +#!/usr/bin/env -S uv run --script +# /// script +# dependencies = [ +# "requests", +# "pyyaml", +# "hvac" +# ] +# /// + +# vim: filetype=python + +""" +RPM Builder Tool + +A Python replacement for the Makefile-based build system. +Builds RPM packages using Docker and checks for existing packages via Gitea API. +""" + +import os +import sys +import argparse +import logging +import subprocess +import requests +from pathlib import Path +from typing import List, Tuple +from concurrent.futures import ThreadPoolExecutor, as_completed +import hvac + + +# ==================== VAULT FUNCTIONS ==================== + +def get_vault_client() -> hvac.Client: + """ + Initialize and authenticate Vault client using AppRole authentication. + + Returns: + Authenticated HVAC client + """ + logger = logging.getLogger(__name__) + + # Get required environment variables + vault_addr = os.getenv('VAULT_ADDR', 'https://vault.service.consul:8200') + vault_role_id = os.getenv('VAULT_ROLE_ID') + + if not vault_role_id: + logger.error("VAULT_ROLE_ID environment variable is required") + raise ValueError("VAULT_ROLE_ID environment variable is required") + + # Initialize Vault client with CA certificate + client = hvac.Client( + url=vault_addr, + verify='/etc/pki/tls/cert.pem' + ) + + # Authenticate using AppRole + try: + logger.debug(f"Authenticating to Vault at {vault_addr}") + auth_response = client.auth.approle.login(role_id=vault_role_id) + + if not client.is_authenticated(): + logger.error("Failed to authenticate with Vault") + raise Exception("Failed to authenticate with Vault") + + logger.debug("Successfully authenticated with Vault") + return client + + except Exception as e: + logger.error(f"Vault authentication failed: {e}") + raise + + +def get_api_tokens() -> Tuple[str, str]: + """ + Retrieve GitHub and Gitea API tokens from Vault. + + Returns: + Tuple of (github_token, gitea_token) + + Raises: + Exception if Vault authentication fails or tokens cannot be retrieved + """ + logger = logging.getLogger(__name__) + + client = get_vault_client() + + # Read GitHub token + try: + github_secret = client.secrets.kv.v2.read_secret_version( + path='service/github/neoloc/tokens/read-only-token' + ) + github_token = github_secret['data']['data']['token'] + logger.debug("Successfully retrieved GitHub token from Vault") + except Exception as e: + logger.error(f"Failed to retrieve GitHub token from Vault: {e}") + raise Exception(f"Failed to retrieve GitHub token from Vault: {e}") + + # Read Gitea token + try: + gitea_secret = client.secrets.kv.v2.read_secret_version( + path='service/gitea/unkinben/tokens/read-only-packages' + ) + gitea_token = gitea_secret['data']['data']['token'] + logger.debug("Successfully retrieved Gitea token from Vault") + except Exception as e: + logger.error(f"Failed to retrieve Gitea token from Vault: {e}") + raise Exception(f"Failed to retrieve Gitea token from Vault: {e}") + + if not github_token or not gitea_token: + logger.error("One or both API tokens are empty") + raise Exception("One or both API tokens are empty") + + return github_token, gitea_token + + +# ==================== GITEA API FUNCTIONS ==================== + +def normalize_version(version: str) -> str: + """ + Normalize version string by removing leading zeros from numeric components. + Gitea automatically does this normalization. + + Examples: + "2025.08.03" -> "2025.8.3" + "1.05.0" -> "1.5.0" + "0.6.1" -> "0.6.1" (no change needed) + + Args: + version: Original version string + + Returns: + Normalized version string + """ + import re + + # Split by common separators and normalize each numeric part + parts = re.split(r'([.\-_])', version) + normalized_parts = [] + + for part in parts: + # If this part is purely numeric and has leading zeros, remove them + if part.isdigit() and len(part) > 1 and part.startswith('0'): + # Remove leading zeros but keep at least one digit + normalized_parts.append(str(int(part))) + else: + normalized_parts.append(part) + + return ''.join(normalized_parts) + + +def check_package_exists(package_name: str, version: str, release: str) -> bool: + """ + Check if a package version exists in the Gitea package registry. + + Args: + package_name: Name of the package + version: Version string + release: Release number + + Returns: + True if package exists, False otherwise + """ + logger = logging.getLogger(__name__) + + # Get configuration from environment + base_url = os.getenv('GITEA_URL', 'https://git.unkin.net') + owner = os.getenv('GITEA_OWNER', 'unkin') + package_type = os.getenv('GITEA_PACKAGE_TYPE', 'rpm') + + # Get API tokens from Vault - fail hard if unavailable + try: + _, gitea_token = get_api_tokens() + except Exception as e: + logger.error(f"Failed to retrieve API tokens from Vault: {e}") + raise Exception(f"Cannot check package existence without Gitea API token: {e}") + + try: + # Normalize version by removing leading zeros (Gitea does this automatically) + # e.g., "2025.08.03" becomes "2025.8.3" + normalized_version = normalize_version(version) + full_version = f"{normalized_version}-{release}" + url = ( + f"{base_url}/api/v1/packages/{owner}/" + f"{package_type}/{package_name}/{full_version}" + ) + + headers = {'Authorization': f'token {gitea_token}'} + + logger.debug(f"Checking package existence: {url}") + response = requests.get(url, headers=headers, timeout=30) + + if response.status_code == 200: + package_info = response.json() + # Package exists if we get package info back + exists = bool(package_info.get('id')) + logger.debug(f"Package {package_name}:{full_version} {'exists' if exists else 'not found'}") + return exists + elif response.status_code == 404: + logger.debug(f"Package {package_name}:{full_version} not found (404)") + return False + elif response.status_code == 401: + logger.error("Authentication failed. Check GITEA_API_TOKEN.") + return False + else: + logger.warning( + f"Unexpected response checking package {package_name}:{full_version}: " + f"{response.status_code} - {response.text}" + ) + return False + + except requests.RequestException as e: + logger.error(f"Failed to check package {package_name}:{version}-{release}: {e}") + return False + + +def get_package_full_name(package_name: str, version: str, release: str) -> str: + """ + Generate the full package name as used in the registry. + + Args: + package_name: Package name + version: Version string + release: Release number + + Returns: + Full package name string + """ + return f"{package_name}-{version}-{release}" + + +# ==================== DOCKER FUNCTIONS ==================== + +def check_docker_available() -> bool: + """ + Check if Docker is available and running. + + Returns: + True if Docker is available, False otherwise + """ + try: + result = subprocess.run( + ['docker', 'version'], + capture_output=True, + text=True, + timeout=10 + ) + return result.returncode == 0 + except (subprocess.TimeoutExpired, FileNotFoundError): + return False + + +def cleanup_container(container_name: str) -> None: + """ + Remove a Docker container. + + Args: + container_name: Name of the container to remove + """ + logger = logging.getLogger(__name__) + try: + remove_args = ['docker', 'rm', container_name] + logger.debug(f"Running: {' '.join(remove_args)}") + subprocess.run(remove_args, capture_output=True, text=True) + except Exception as e: + logger.warning(f"Failed to remove container {container_name}: {e}") + + +def get_base_image_from_metadata(package_dir: Path, distro: str = "el/9") -> str: + """ + Get the base image from package metadata.yaml. + + Args: + package_dir: Directory containing the package + distro: Target distro (default: el/9) + + Returns: + Base image URL or default if not found + """ + metadata_file = package_dir / "metadata.yaml" + default_image = "git.unkin.net/unkin/almalinux9-rpmbuilder:latest" + + if not metadata_file.exists(): + return default_image + + try: + import yaml + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + build_configs = metadata.get('build', []) + for config in build_configs: + if config.get('distro') == distro: + return config.get('image', default_image) + + # If no matching distro found, return first image or default + if build_configs: + return build_configs[0].get('image', default_image) + + return default_image + + except Exception: + return default_image + + +def build_package_docker( + package_dir: Path, + package_name: str, + package_version: str, + package_release: str, + dist_dir: Path, + base_image: str = "git.unkin.net/unkin/almalinux9-rpmbuilder:latest", + dry_run: bool = False +) -> bool: + """ + Build a package using Docker with central Dockerfile. + + Args: + package_dir: Directory containing the package resources + package_name: Name of the package + package_version: Package version + package_release: Package release number + dist_dir: Directory to store built packages + base_image: Base Docker image to use for building + dry_run: If True, only show what would be done + + Returns: + True if build succeeded, False otherwise + """ + logger = logging.getLogger(__name__) + + try: + # Ensure dist directory exists + package_dist_dir = dist_dir / package_name + if not dry_run: + package_dist_dir.mkdir(parents=True, exist_ok=True) + + # Generate Docker image name + image_name = f"{package_name.lower()}-builder" + container_name = f"{package_name}-{package_version}-builder" + + logger.info(f"Building RPM for {package_name} version {package_version}") + + if dry_run: + logger.info(f"[DRY RUN] Would build Docker image: {image_name}") + logger.info(f"[DRY RUN] Would use base image: {base_image}") + logger.info(f"[DRY RUN] Would create container: {container_name}") + logger.info(f"[DRY RUN] Would copy artifacts to: {package_dist_dir}") + return True + + # Step 1: Build Docker image using central Dockerfile + central_dockerfile = package_dir.parent.parent / "Dockerfile" + build_args = [ + 'docker', 'build', + '-f', str(central_dockerfile), + '--build-arg', f'BASE_IMAGE={base_image}', + '--build-arg', f'PACKAGE_VERSION={package_version}', + '--build-arg', f'PACKAGE_RELEASE={package_release}', + '-t', image_name, + str(package_dir) + ] + + logger.debug(f"Running: {' '.join(build_args)}") + result = subprocess.run( + build_args, + capture_output=True, + text=True, + cwd=package_dir + ) + + if result.returncode != 0: + logger.error(f"Docker build failed for {package_name}") + logger.error(f"stdout: {result.stdout}") + logger.error(f"stderr: {result.stderr}") + return False + + # Step 2: Create and start container + create_args = [ + 'docker', 'create', + '--name', container_name, + image_name + ] + + logger.debug(f"Running: {' '.join(create_args)}") + result = subprocess.run(create_args, capture_output=True, text=True) + + if result.returncode != 0: + logger.error(f"Container creation failed for {package_name}") + logger.error(f"stderr: {result.stderr}") + return False + + try: + # Step 3: Start container + start_args = ['docker', 'start', '-a', container_name] + logger.debug(f"Running: {' '.join(start_args)}") + result = subprocess.run(start_args, capture_output=True, text=True) + + if result.returncode != 0: + logger.error(f"Container execution failed for {package_name}") + logger.error(f"stdout: {result.stdout}") + logger.error(f"stderr: {result.stderr}") + return False + + # Step 4: Copy artifacts + copy_args = [ + 'docker', 'cp', + f"{container_name}:/app/dist/.", + str(package_dist_dir) + "/" + ] + + logger.debug(f"Running: {' '.join(copy_args)}") + result = subprocess.run(copy_args, capture_output=True, text=True) + + if result.returncode != 0: + logger.error(f"Failed to copy artifacts for {package_name}") + logger.error(f"stderr: {result.stderr}") + return False + + logger.info(f"Successfully built {package_name}-{package_version}-{package_release}") + return True + + finally: + # Step 5: Clean up container + cleanup_container(container_name) + + except Exception as e: + logger.error(f"Unexpected error building {package_name}: {e}") + return False + + +def cleanup_images(image_pattern: str = "*-builder") -> None: + """ + Clean up Docker images matching a pattern. + + Args: + image_pattern: Pattern to match image names + """ + logger = logging.getLogger(__name__) + try: + # List images matching pattern + list_args = ['docker', 'images', '--format', '{{.Repository}}', '--filter', f'reference={image_pattern}'] + result = subprocess.run(list_args, capture_output=True, text=True) + + if result.returncode == 0 and result.stdout.strip(): + images = result.stdout.strip().split('\n') + if images: + remove_args = ['docker', 'rmi'] + images + subprocess.run(remove_args, capture_output=True, text=True) + logger.info(f"Cleaned up {len(images)} Docker images") + except Exception as e: + logger.warning(f"Failed to clean up Docker images: {e}") + + +# ==================== PACKAGE INFO CLASS ==================== + +class PackageInfo: + """Information about a package to build.""" + + def __init__(self, name: str, version: str, release: str, directory: Path, distro: str = 'el/9', base_image: str = None): + self.name = name + self.version = version + self.release = release + self.directory = directory + self.distro = distro + self.base_image = base_image or "git.unkin.net/unkin/almalinux9-rpmbuilder:latest" + + def __str__(self): + return f"{self.name}-{self.version}-{self.release} ({self.distro})" + + +# ==================== BUILDER CLASS ==================== + +class Builder: + """Main builder class that orchestrates package building.""" + + def __init__(self, root_dir: Path): + """ + Initialize the builder. + + Args: + root_dir: Root directory of the project + """ + self.root_dir = root_dir + self.rpms_dir = root_dir / "rpms" + self.dist_dir = root_dir / "dist" + + self.logger = logging.getLogger(__name__) + + # Ensure dist directory exists + self.dist_dir.mkdir(exist_ok=True) + + def discover_packages(self, distro: str = 'el/9') -> List[PackageInfo]: + """ + Discover all packages and their versions from metadata.yaml files. + + Args: + distro: Target distro (e.g., 'el/8', 'el/9', 'all') + + Returns: + List of PackageInfo objects + """ + packages = [] + + if not self.rpms_dir.exists(): + self.logger.error(f"RPMs directory not found: {self.rpms_dir}") + return packages + + for package_dir in self.rpms_dir.iterdir(): + if not package_dir.is_dir() or package_dir.name.startswith('.'): + continue + + metadata_file = package_dir / "metadata.yaml" + if not metadata_file.exists(): + self.logger.warning(f"No metadata.yaml found for {package_dir.name}") + continue + + try: + import yaml + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + package_name = metadata.get('name', package_dir.name) + version = metadata.get('version') + release = metadata.get('release') + build_configs = metadata.get('build', []) + + if not version: + self.logger.warning(f"No version in metadata.yaml for {package_name}") + continue + + if not release: + self.logger.warning(f"No release in metadata.yaml for {package_name}") + continue + + # Handle distro filtering + if distro == 'all': + # Build for all configured distros + for build_config in build_configs: + if isinstance(build_config, dict): + build_distro = build_config.get('distro') + base_image = build_config.get('image') + if build_distro and base_image: + packages.append(PackageInfo(package_name, version, str(release), package_dir, build_distro, base_image)) + else: + # Build for specific distro + for build_config in build_configs: + if isinstance(build_config, dict) and build_config.get('distro') == distro: + base_image = build_config.get('image') + if base_image: + packages.append(PackageInfo(package_name, version, str(release), package_dir, distro, base_image)) + break + else: + # If no matching distro found, log a warning + self.logger.debug(f"No build config for {distro} found for {package_name}") + + except Exception as e: + self.logger.error(f"Error reading metadata.yaml for {package_dir.name}: {e}") + continue + + return packages + + def build_single( + self, + package: str, + version: str, + release: str, + dry_run: bool = False, + force: bool = False, + distro: str = 'el/9' + ) -> bool: + """ + Build a single package. + + Args: + package: Package name + version: Package version + release: Package release + dry_run: If True, only show what would be done + force: If True, build even if package exists + distro: Target distro (e.g., 'el/8', 'el/9', 'all') + + Returns: + True if build succeeded, False otherwise + """ + package_dir = self.rpms_dir / package + + if not package_dir.exists(): + self.logger.error(f"Package directory not found: {package_dir}") + return False + + # Read metadata.yaml to validate version/release + metadata_file = package_dir / "metadata.yaml" + if not metadata_file.exists(): + self.logger.error(f"metadata.yaml not found: {metadata_file}") + return False + + try: + import yaml + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + metadata_version = metadata.get('version') + metadata_release = metadata.get('release') + + if metadata_version != version: + self.logger.error( + f"Version mismatch for {package}: " + f"provided {version} but metadata.yaml has {metadata_version}" + ) + return False + + if str(metadata_release) != str(release): + self.logger.error( + f"Release mismatch for {package}: " + f"provided {release} but metadata.yaml has {metadata_release}" + ) + return False + + # Find base image for the specified distro + build_configs = metadata.get('build', []) + base_image = None + + if distro == 'all': + # For single package build, 'all' doesn't make sense, default to el/9 + distro = 'el/9' + + for build_config in build_configs: + if isinstance(build_config, dict) and build_config.get('distro') == distro: + base_image = build_config.get('image') + break + + if not base_image: + self.logger.error(f"No build configuration found for distro {distro} in {package}") + return False + + except Exception as e: + self.logger.error(f"Error reading metadata.yaml for {package}: {e}") + return False + + package_info = PackageInfo(package, version, release, package_dir, distro, base_image) + return self._build_package(package_info, dry_run, force) + + def build_all(self, dry_run: bool = False, force: bool = False, parallel: int = 4, distro: str = 'el/9') -> bool: + """ + Build all packages. + + Args: + dry_run: If True, only show what would be done + force: If True, build even if packages exist + parallel: Number of parallel builds + distro: Target distro (e.g., 'el/8', 'el/9', 'all') + + Returns: + True if all builds succeeded, False otherwise + """ + packages = self.discover_packages(distro) + + if not packages: + self.logger.warning("No packages found to build") + return True + + self.logger.info(f"Found {len(packages)} packages to process") + + if parallel == 1: + return self._build_sequential(packages, dry_run, force) + else: + return self._build_parallel(packages, dry_run, force, parallel) + + def _build_sequential(self, packages: List[PackageInfo], dry_run: bool, force: bool) -> bool: + """Build packages sequentially.""" + success_count = 0 + + for package_info in packages: + if self._build_package(package_info, dry_run, force): + success_count += 1 + + self.logger.info(f"Built {success_count}/{len(packages)} packages successfully") + return success_count == len(packages) + + def _build_parallel(self, packages: List[PackageInfo], dry_run: bool, force: bool, parallel: int) -> bool: + """Build packages in parallel.""" + success_count = 0 + + with ThreadPoolExecutor(max_workers=parallel) as executor: + # Submit all build tasks + future_to_package = { + executor.submit(self._build_package, pkg, dry_run, force): pkg + for pkg in packages + } + + # Process completed builds + for future in as_completed(future_to_package): + package_info = future_to_package[future] + try: + success = future.result() + if success: + success_count += 1 + except Exception as e: + self.logger.error(f"Build failed for {package_info}: {e}") + + self.logger.info(f"Built {success_count}/{len(packages)} packages successfully") + return success_count == len(packages) + + def _build_package(self, package_info: PackageInfo, dry_run: bool, force: bool) -> bool: + """ + Build a single package. + + Args: + package_info: Package information + dry_run: If True, only show what would be done + force: If True, build even if package exists + + Returns: + True if build succeeded, False otherwise + """ + try: + # Check if package already exists (unless forced) + if not force: + if check_package_exists( + package_info.name, + package_info.version, + package_info.release + ): + self.logger.info( + f"Skipping {package_info} (already exists in repository)" + ) + return True + + # Check Docker is available (unless dry run) + if not dry_run and not check_docker_available(): + self.logger.error("Docker is not available or running") + return False + + # Build the package + return build_package_docker( + package_dir=package_info.directory, + package_name=package_info.name, + package_version=package_info.version, + package_release=package_info.release, + dist_dir=self.dist_dir, + base_image=package_info.base_image, + dry_run=dry_run + ) + + except Exception as e: + self.logger.error(f"Failed to build {package_info}: {e}") + return False + + def list_packages(self) -> None: + """List all available packages.""" + packages = self.discover_packages() + + if not packages: + print("No packages found") + return + + print("Available packages:") + for package_info in sorted(packages, key=lambda p: (p.name, p.version)): + print(f" {package_info}") + + def clean_dist(self) -> None: + """Clean the dist directory.""" + if self.dist_dir.exists(): + import shutil + shutil.rmtree(self.dist_dir) + self.dist_dir.mkdir() + self.logger.info("Cleaned dist directory") + + +# ==================== MAIN FUNCTIONS ==================== + +def setup_logging(verbose=False): + """Set up logging configuration.""" + level = logging.DEBUG if verbose else logging.INFO + logging.basicConfig( + level=level, + format='%(asctime)s - %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + +def main(): + """Main entry point.""" + parser = argparse.ArgumentParser( + description='Build RPM packages using Docker', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s --package consul --version 1.21.1 --release 1 + %(prog)s --package consul (uses version/release from metadata.yaml) + %(prog)s --package consul --distro el/8 (build for el/8) + %(prog)s --all (builds all packages for el/9 by default) + %(prog)s --all --distro el/8 (builds all packages for el/8) + %(prog)s --all --distro all (builds all packages for all distros) + %(prog)s --all --dry-run + """ + ) + + # Package selection arguments + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('--package', help='Package name to build') + group.add_argument('--all', action='store_true', help='Build all packages') + + # Version and release (optional for single package builds, read from metadata.yaml if not provided) + parser.add_argument('--version', help='Package version (optional, read from metadata.yaml if not provided)') + parser.add_argument('--release', help='Package release number (optional, read from metadata.yaml if not provided)') + + # Optional arguments + parser.add_argument('--distro', default='el/9', help='Build for specific distro (default: el/9). Use "all" to build for all distros.') + parser.add_argument('--dry-run', action='store_true', help='Show what would be built without building') + parser.add_argument('--force', action='store_true', help='Build even if package exists in registry') + parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging') + parser.add_argument('--parallel', type=int, default=4, help='Number of parallel builds (default: 4)') + + args = parser.parse_args() + + # No validation needed - version/release will be read from metadata.yaml if not provided + + setup_logging(args.verbose) + + try: + # Initialize components + root_dir = Path(__file__).parent.parent + builder = Builder(root_dir) + + # Execute build + if args.all: + success = builder.build_all( + dry_run=args.dry_run, + force=args.force, + parallel=args.parallel, + distro=args.distro + ) + else: + # Read version/release from metadata.yaml if not provided + version = args.version + release = args.release + + if not version or not release: + package_dir = builder.rpms_dir / args.package + metadata_file = package_dir / "metadata.yaml" + + if not metadata_file.exists(): + logging.error(f"metadata.yaml not found for package {args.package}") + sys.exit(1) + + try: + import yaml + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + if not version: + version = metadata.get('version') + if not version: + logging.error(f"No version in metadata.yaml for {args.package}") + sys.exit(1) + + if not release: + release = metadata.get('release') + if not release: + logging.error(f"No release in metadata.yaml for {args.package}") + sys.exit(1) + + except Exception as e: + logging.error(f"Error reading metadata.yaml for {args.package}: {e}") + sys.exit(1) + + success = builder.build_single( + package=args.package, + version=version, + release=str(release), + dry_run=args.dry_run, + force=args.force, + distro=args.distro + ) + + sys.exit(0 if success else 1) + + except KeyboardInterrupt: + logging.info("Build interrupted by user") + sys.exit(130) + except Exception as e: + logging.error(f"Build failed: {e}") + if args.verbose: + logging.exception("Full traceback:") + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/tools/update-gh b/tools/update-gh new file mode 100755 index 0000000..90b66ed --- /dev/null +++ b/tools/update-gh @@ -0,0 +1,460 @@ +#!/usr/bin/env -S uv run --script +# /// script +# dependencies = [ +# "requests", +# "pyyaml", +# "hvac" +# ] +# /// + +# vim: filetype=python + +""" +GitHub Release Update Tool + +Checks GitHub releases for packages and updates metadata.yaml and release files +when newer versions are available. +""" + +import os +import sys +import argparse +import logging +import requests +import yaml +from pathlib import Path +from typing import Dict, Optional, List, Tuple +import re +import hvac + + +# ==================== VAULT FUNCTIONS ==================== + +def get_vault_client() -> hvac.Client: + """ + Initialize and authenticate Vault client using AppRole authentication. + + Returns: + Authenticated HVAC client + """ + logger = logging.getLogger(__name__) + + # Get required environment variables + vault_addr = os.getenv('VAULT_ADDR', 'https://vault.service.consul:8200') + vault_role_id = os.getenv('VAULT_ROLE_ID') + + if not vault_role_id: + logger.error("VAULT_ROLE_ID environment variable is required") + raise ValueError("VAULT_ROLE_ID environment variable is required") + + # Initialize Vault client with CA certificate + client = hvac.Client( + url=vault_addr, + verify='/etc/pki/tls/cert.pem' + ) + + # Authenticate using AppRole + try: + logger.debug(f"Authenticating to Vault at {vault_addr}") + auth_response = client.auth.approle.login(role_id=vault_role_id) + + if not client.is_authenticated(): + logger.error("Failed to authenticate with Vault") + raise Exception("Failed to authenticate with Vault") + + logger.debug("Successfully authenticated with Vault") + return client + + except Exception as e: + logger.error(f"Vault authentication failed: {e}") + raise + + +def get_api_tokens() -> Tuple[str, str]: + """ + Retrieve GitHub and Gitea API tokens from Vault. + + Returns: + Tuple of (github_token, gitea_token) + + Raises: + Exception if Vault authentication fails or tokens cannot be retrieved + """ + logger = logging.getLogger(__name__) + + client = get_vault_client() + + # Read GitHub token + try: + github_secret = client.secrets.kv.v2.read_secret_version( + path='service/github/neoloc/tokens/read-only-token' + ) + github_token = github_secret['data']['data']['token'] + logger.debug("Successfully retrieved GitHub token from Vault") + except Exception as e: + logger.error(f"Failed to retrieve GitHub token from Vault: {e}") + raise Exception(f"Failed to retrieve GitHub token from Vault: {e}") + + # Read Gitea token + try: + gitea_secret = client.secrets.kv.v2.read_secret_version( + path='service/gitea/unkinben/tokens/read-only-packages' + ) + gitea_token = gitea_secret['data']['data']['token'] + logger.debug("Successfully retrieved Gitea token from Vault") + except Exception as e: + logger.error(f"Failed to retrieve Gitea token from Vault: {e}") + raise Exception(f"Failed to retrieve Gitea token from Vault: {e}") + + if not github_token or not gitea_token: + logger.error("One or both API tokens are empty") + raise Exception("One or both API tokens are empty") + + return github_token, gitea_token + + +def setup_logging(verbose=False): + """Set up logging configuration.""" + level = logging.DEBUG if verbose else logging.INFO + logging.basicConfig( + level=level, + format='%(asctime)s - %(levelname)s - %(message)s', + datefmt='%H:%M:%S' + ) + + +def load_env_vars(env_file: Path) -> Dict[str, str]: + """ + Load environment variables from env file. + + Args: + env_file: Path to the env file + + Returns: + Dictionary of environment variables + """ + env_vars = {} + + if not env_file.exists(): + return env_vars + + with open(env_file, 'r') as f: + for line in f: + line = line.strip() + if line and not line.startswith('#') and '=' in line: + # Handle export statements + if line.startswith('export '): + line = line[7:] # Remove 'export ' + + key, value = line.split('=', 1) + env_vars[key.strip()] = value.strip() + + return env_vars + + +def get_github_latest_release(repo: str) -> Optional[Dict]: + """ + Get the latest release from GitHub API. + + Args: + repo: GitHub repository in format "owner/repo" + + Returns: + Latest release info or None if not found + """ + logger = logging.getLogger(__name__) + + try: + # Get GitHub token from Vault + github_token, _ = get_api_tokens() + + url = f"https://api.github.com/repos/{repo}/releases/latest" + headers = { + 'Authorization': f'token {github_token}', + 'Accept': 'application/vnd.github.v3+json' + } + + logger.debug(f"Checking GitHub releases: {url}") + response = requests.get(url, headers=headers, timeout=30) + + if response.status_code == 200: + release = response.json() + logger.debug(f"Latest release for {repo}: {release.get('tag_name', 'unknown')}") + return release + elif response.status_code == 404: + logger.warning(f"No releases found for {repo}") + return None + elif response.status_code == 401: + logger.error("GitHub authentication failed. Check GITHUB_API_TOKEN.") + return None + else: + logger.warning( + f"Unexpected response from GitHub API for {repo}: " + f"{response.status_code} - {response.text}" + ) + return None + + except requests.RequestException as e: + logger.error(f"Failed to check GitHub releases for {repo}: {e}") + return None + + +def normalize_version(version: str) -> str: + """ + Normalize version string by removing 'v' prefix if present. + + Args: + version: Version string (e.g., "v1.2.3" or "1.2.3") + + Returns: + Normalized version string (e.g., "1.2.3") + """ + if version.startswith('v'): + return version[1:] + return version + + +def compare_versions(current: str, latest: str) -> bool: + """ + Compare version strings to determine if latest is newer. + This is a simple string comparison that works for semantic versions. + + Args: + current: Current version string + latest: Latest version string + + Returns: + True if latest is newer than current + """ + def version_tuple(v): + # Split by dots and convert to integers where possible + parts = [] + for part in v.split('.'): + try: + parts.append(int(part)) + except ValueError: + # Handle non-numeric parts + parts.append(part) + return tuple(parts) + + try: + return version_tuple(latest) > version_tuple(current) + except: + # Fallback to string comparison + return latest != current + + +def update_package_metadata(package_dir: Path, new_version: str, dry_run: bool = False) -> bool: + """ + Update package metadata.yaml with new version. + + Args: + package_dir: Path to package directory + new_version: New version to update to + dry_run: If True, only show what would be done + + Returns: + True if update was successful + """ + logger = logging.getLogger(__name__) + metadata_file = package_dir / "metadata.yaml" + + try: + # Load current metadata + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + old_version = metadata.get('version', 'unknown') + logger.info(f"Updating {metadata.get('name', 'unknown')} from {old_version} to {new_version}") + + if dry_run: + logger.info(f"[DRY RUN] Would update metadata.yaml version to {new_version}") + return True + + # Update version in metadata and reset release to 1 + metadata['version'] = new_version + metadata['release'] = 1 + + # Write updated metadata + with open(metadata_file, 'w') as f: + yaml.dump(metadata, f, default_flow_style=False, sort_keys=False) + + logger.info(f"Successfully updated {metadata.get('name')} to version {new_version}") + return True + + except Exception as e: + logger.error(f"Failed to update package metadata: {e}") + return False + + +def check_package_updates(package_dir: Path, dry_run: bool = False) -> bool: + """ + Check for updates for a single package. + + Args: + package_dir: Path to package directory + dry_run: If True, only show what would be done + + Returns: + True if package was updated or no update needed + """ + logger = logging.getLogger(__name__) + metadata_file = package_dir / "metadata.yaml" + + if not metadata_file.exists(): + logger.warning(f"No metadata.yaml found in {package_dir}") + return False + + try: + # Load metadata + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + package_name = metadata.get('name', package_dir.name) + current_version = metadata.get('version') + github_repo = metadata.get('github') + + if not github_repo: + logger.debug(f"Package {package_name} has no GitHub repo configured") + return True + + if not current_version: + logger.warning(f"Package {package_name} has no version in metadata") + return False + + logger.info(f"Checking {package_name} (current: {current_version}) from {github_repo}") + + # Get latest release from GitHub + latest_release = get_github_latest_release(github_repo) + if not latest_release: + return False + + latest_version = normalize_version(latest_release.get('tag_name', '')) + if not latest_version: + logger.warning(f"Could not determine latest version for {package_name}") + return False + + # Compare versions + if compare_versions(current_version, latest_version): + logger.info(f"New version available: {current_version} -> {latest_version}") + return update_package_metadata(package_dir, latest_version, dry_run) + else: + logger.info(f"Package {package_name} is up to date ({current_version})") + return True + + except Exception as e: + logger.error(f"Failed to check package {package_dir.name}: {e}") + return False + + +def find_packages_with_github(rpms_dir: Path) -> List[Path]: + """ + Find all packages that have GitHub repo configured. + + Args: + rpms_dir: Path to rpms directory + + Returns: + List of package directories with GitHub repos + """ + github_packages = [] + + for package_dir in rpms_dir.iterdir(): + if not package_dir.is_dir() or package_dir.name.startswith('.'): + continue + + metadata_file = package_dir / "metadata.yaml" + if not metadata_file.exists(): + continue + + try: + with open(metadata_file, 'r') as f: + metadata = yaml.safe_load(f) + + if metadata.get('github'): + github_packages.append(package_dir) + except Exception: + continue + + return github_packages + + +def main(): + """Main entry point.""" + parser = argparse.ArgumentParser( + description='Check GitHub releases and update package metadata', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + %(prog)s --package boilerplate + %(prog)s --all + %(prog)s --all --dry-run + """ + ) + + # Package selection arguments + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('--package', help='Package name to check') + group.add_argument('--all', action='store_true', help='Check all packages with GitHub repos') + + # Optional arguments + parser.add_argument('--dry-run', action='store_true', help='Show what would be done without making changes') + parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose logging') + + args = parser.parse_args() + + setup_logging(args.verbose) + logger = logging.getLogger(__name__) + + try: + # Get root directory and load environment + root_dir = Path(__file__).parent.parent + rpms_dir = root_dir / "rpms" + env_file = root_dir / "env" + + if not rpms_dir.exists(): + logger.error(f"RPMs directory not found: {rpms_dir}") + sys.exit(1) + + success = True + + if args.package: + # Check single package + package_dir = rpms_dir / args.package + if not package_dir.exists(): + logger.error(f"Package directory not found: {package_dir}") + sys.exit(1) + + success = check_package_updates(package_dir, args.dry_run) + else: + # Check all packages with GitHub repos + github_packages = find_packages_with_github(rpms_dir) + + if not github_packages: + logger.info("No packages with GitHub repos found") + sys.exit(0) + + logger.info(f"Found {len(github_packages)} packages with GitHub repos") + + updated_count = 0 + for package_dir in github_packages: + if check_package_updates(package_dir, args.dry_run): + updated_count += 1 + + logger.info(f"Successfully processed {updated_count}/{len(github_packages)} packages") + success = updated_count == len(github_packages) + + sys.exit(0 if success else 1) + + except KeyboardInterrupt: + logger.info("Update check interrupted by user") + sys.exit(130) + except Exception as e: + logger.error(f"Update check failed: {e}") + if args.verbose: + logger.exception("Full traceback:") + sys.exit(1) + + +if __name__ == '__main__': + main() \ No newline at end of file