name: release # Manual release pipeline (Gitea Actions). # # Order / gating (".deb is the source of truth, hosted/image must not build without it"): # prepare ──► build-deb ──► build-image ──► package-helm # └──► package-hosted # build-image and package-hosted additionally verify the .deb exists in the # registry before doing anything (belt-and-suspenders gate). # # Required repo secrets: # PACKAGES_USER Gitea username (token owner) # PACKAGES_TOKEN Gitea access token with write:package (+ read:package) on: workflow_dispatch: inputs: rlm_raw_branch: description: rlm_raw module branch required: false default: v3.2.4 concurrency: group: release cancel-in-progress: false env: REGISTRY: git.ahax86.ru OWNER: pub IMAGE: git.ahax86.ru/pub/freeradius DEB_REGISTRY: https://git.ahax86.ru/api/packages/pub/debian DEB_DISTRIBUTION: noble DEB_COMPONENT: main jobs: prepare: runs-on: ubuntu-latest outputs: version: ${{ steps.v.outputs.version }} radius_tag: ${{ steps.v.outputs.radius_tag }} pkg_version: ${{ steps.v.outputs.pkg_version }} steps: - uses: actions/checkout@v4 - id: v name: Resolve version from /VERSION run: | set -euo pipefail version="$(tr -d ' \n\r' < VERSION)" radius_tag="release_$(echo "$version" | tr '.' '_')" pkg_version="${version}+git" echo "version=$version" >> "$GITHUB_OUTPUT" echo "radius_tag=$radius_tag" >> "$GITHUB_OUTPUT" echo "pkg_version=$pkg_version" >> "$GITHUB_OUTPUT" echo "version=$version tag=$radius_tag pkg=$pkg_version" - name: Check version consistency run: | set -euo pipefail version="$(tr -d ' \n\r' < VERSION)" env_tag="$(grep -E '^FREERADIUS_TAG=' packaging/hosted/.env | cut -d= -f2 | tr -d ' \r')" chart_app="$(grep -E '^appVersion:' charts/freeradius/Chart.yaml | sed -E 's/appVersion:[[:space:]]*"?([^"]+)"?/\1/' | tr -d ' \r')" [ "$env_tag" = "$version" ] || { echo "hosted/.env FREERADIUS_TAG=$env_tag != VERSION=$version"; exit 1; } [ "$chart_app" = "$version" ] || { echo "Chart appVersion=$chart_app != VERSION=$version"; exit 1; } echo "Versions consistent: $version" build-deb: needs: [prepare] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build .deb builder image run: | docker build packaging/deb -f packaging/deb/Dockerfile \ --build-arg RADIUS_TAG=${{ needs.prepare.outputs.radius_tag }} \ --build-arg RLM_RAW_BRANCH=${{ inputs.rlm_raw_branch }} \ -t freerad-builder:${{ needs.prepare.outputs.version }} - name: Upload .deb to Gitea Debian registry env: DEB_USER: ${{ secrets.PACKAGES_USER }} DEB_PASS: ${{ secrets.PACKAGES_TOKEN }} run: | docker run --rm \ -e DEB_USER -e DEB_PASS \ -e DEB_REGISTRY="${{ env.DEB_REGISTRY }}" \ -e DEB_DISTRIBUTION="${{ env.DEB_DISTRIBUTION }}" \ -e DEB_COMPONENT="${{ env.DEB_COMPONENT }}" \ freerad-builder:${{ needs.prepare.outputs.version }} ./upload.sh build-image: needs: [prepare, build-deb] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Verify .deb is published env: DEB_USER: ${{ secrets.PACKAGES_USER }} DEB_PASS: ${{ secrets.PACKAGES_TOKEN }} run: | set -euo pipefail url="${{ env.DEB_REGISTRY }}/dists/${{ env.DEB_DISTRIBUTION }}/${{ env.DEB_COMPONENT }}/binary-amd64/Packages" curl -fsSL --user "$DEB_USER:$DEB_PASS" "$url" \ | grep -q "Version: ${{ needs.prepare.outputs.pkg_version }}" \ || { echo "Package ${{ needs.prepare.outputs.pkg_version }} not found in registry"; exit 1; } - name: Login to container registry run: echo "${{ secrets.PACKAGES_TOKEN }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.PACKAGES_USER }}" --password-stdin - name: Build and push image run: | set -euo pipefail docker build -f packaging/image/Dockerfile \ --build-arg PKG_VERSION=${{ needs.prepare.outputs.pkg_version }} \ -t ${{ env.IMAGE }}:${{ needs.prepare.outputs.version }} \ -t ${{ env.IMAGE }}:latest . docker push ${{ env.IMAGE }}:${{ needs.prepare.outputs.version }} docker push ${{ env.IMAGE }}:latest package-hosted: needs: [prepare, build-deb] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Verify .deb is published env: DEB_USER: ${{ secrets.PACKAGES_USER }} DEB_PASS: ${{ secrets.PACKAGES_TOKEN }} run: | set -euo pipefail url="${{ env.DEB_REGISTRY }}/dists/${{ env.DEB_DISTRIBUTION }}/${{ env.DEB_COMPONENT }}/binary-amd64/Packages" curl -fsSL --user "$DEB_USER:$DEB_PASS" "$url" \ | grep -q "Version: ${{ needs.prepare.outputs.pkg_version }}" \ || { echo "Package ${{ needs.prepare.outputs.pkg_version }} not found in registry"; exit 1; } - name: Package and upload hosted bundle env: PKG_USER: ${{ secrets.PACKAGES_USER }} PKG_TOKEN: ${{ secrets.PACKAGES_TOKEN }} run: | set -euo pipefail chmod +x packaging/hosted/install.sh packaging/hosted/update.sh tar -czf freeradius-hosted.tar.gz -C packaging hosted ver="${{ needs.prepare.outputs.version }}" curl -fsSL --user "$PKG_USER:$PKG_TOKEN" \ --upload-file freeradius-hosted.tar.gz \ "https://${{ env.REGISTRY }}/api/packages/${{ env.OWNER }}/generic/freeradius-hosted/${ver}/freeradius-hosted.tar.gz" package-helm: needs: [prepare, build-image] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install helm run: curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash - name: Lint chart run: helm lint charts/freeradius --set db.password=ci - name: Package and push chart env: PKG_USER: ${{ secrets.PACKAGES_USER }} PKG_TOKEN: ${{ secrets.PACKAGES_TOKEN }} run: | set -euo pipefail helm package charts/freeradius --app-version "${{ needs.prepare.outputs.version }}" -d dist chart="$(ls dist/*.tgz)" curl -fsSL --user "$PKG_USER:$PKG_TOKEN" -X POST \ --upload-file "$chart" \ "https://${{ env.REGISTRY }}/api/packages/${{ env.OWNER }}/helm/api/charts"