From bf643393adf74f71af926867a0c7e7558cf1e951 Mon Sep 17 00:00:00 2001 From: Anton Kuznetcov Date: Mon, 28 Jul 2025 14:05:01 +0600 Subject: [PATCH] Release v1.0.30 --- .gitea/workflows/build.yaml | 7 +- build.yaml | 124 ---------------- docs/gitea-actions-guide.md | 255 ++++++++++++++++++++++----------- main.go | 2 +- makefile | 2 +- scripts/release-interactive.sh | 2 +- 6 files changed, 183 insertions(+), 209 deletions(-) delete mode 100644 build.yaml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index b131bb0..042acb6 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -21,7 +21,7 @@ jobs: - name: Setup Go run: | # Install jq for JSON parsing - apt-get update && apt-get install -y jq + # apt-get update && apt-get install -y jq git --version go version jq --version @@ -106,7 +106,7 @@ jobs: docker --version # Setup Docker Buildx for multi-platform builds - docker buildx create --use + docker buildx create --name go-buildx --use docker buildx inspect --bootstrap - name: Login to Docker Hub @@ -123,6 +123,9 @@ jobs: --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:latest \ --push \ . + - name: Remove buildx + run: | + docker buildx rm go-buildx update-to-release-branch: runs-on: ubuntu-latest diff --git a/build.yaml b/build.yaml deleted file mode 100644 index 69c1187..0000000 --- a/build.yaml +++ /dev/null @@ -1,124 +0,0 @@ -name: Release Build -on: - push: - tags: - - v* - -jobs: - create-docker-image: - runs-on: ubuntu-latest - container: - image: docker:28.3.2-dind - steps: - - name: Checkout repository - run: | - # Install git - apk add --no-cache git - - echo "=== GitHub Variables ===" - echo "github.ref = ${{ github.ref }}" - echo "github.ref_name = ${{ github.ref_name }}" - echo "github.sha = ${{ github.sha }}" - echo "github.repository = ${{ github.repository }}" - echo "========================" - git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea - cd hello_gitea - git checkout ${{ github.ref }} - - - name: Setup Docker Buildx - run: | - # Docker is already installed in docker:dind image - docker --version - - # Setup Docker Buildx for multi-platform builds - docker buildx create --use - docker buildx inspect --bootstrap - - - name: Login to Docker Hub - run: | - echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - - - name: Build multi-platform Docker images - run: | - cd hello_gitea - # Build multi-platform images using buildx - docker buildx build \ - --platform linux/amd64,linux/arm64 \ - --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:${{ github.ref_name }} \ - --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:latest \ - --push \ - . - - create-release: - runs-on: ubuntu-latest - container: - # image: golang:1.21 - image: ${{ secrets.DOCKERHUB_USERNAME }}/my-build-golang-runner:latest - needs: create-docker-image - steps: - - name: Checkout repository - run: | - git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea - cd hello_gitea - git checkout ${{ github.ref }} - - - name: Setup Go - run: | - # Install jq for JSON parsing - apt-get update && apt-get install -y jq - git --version - go version - jq --version - - - name: Build all binaries - run: | - cd hello_gitea - mkdir -p bin - - # Build for all platforms - GOOS=linux GOARCH=amd64 go build -o bin/hello-api-linux-amd64 main.go - GOOS=linux GOARCH=arm64 go build -o bin/hello-api-linux-arm64 main.go - GOOS=windows GOARCH=amd64 go build -o bin/hello-api-windows-amd64.exe main.go - GOOS=darwin GOARCH=amd64 go build -o bin/hello-api-darwin-amd64 main.go - GOOS=darwin GOARCH=arm64 go build -o bin/hello-api-darwin-arm64 main.go - - # Create archives - cd bin - tar -czf hello-api-linux-amd64.tar.gz hello-api-linux-amd64 - tar -czf hello-api-linux-arm64.tar.gz hello-api-linux-arm64 - tar -czf hello-api-windows-amd64.tar.gz hello-api-windows-amd64.exe - tar -czf hello-api-darwin-amd64.tar.gz hello-api-darwin-amd64 - tar -czf hello-api-darwin-arm64.tar.gz hello-api-darwin-arm64 - - ls -la - - - name: Create Release - run: | - cd hello_gitea - # Create release using Gitea API - curl -X POST \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -H "Content-Type: application/json" \ - -d '{ - "tag_name": "${{ github.ref_name }}", - "name": "Release ${{ github.ref_name }}", - "body": "Automated release with multi-platform binaries and Docker image", - "draft": false, - "prerelease": false - }' \ - "https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases" - - # Upload assets - RELEASE_ID=$(curl -s -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - "https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases/tags/${{ github.ref_name }}" | \ - jq -r '.id') - - # Upload all binaries - for file in bin/*.tar.gz; do - echo "Uploading $file..." - curl -X POST \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -H "Content-Type: application/octet-stream" \ - --data-binary @$file \ - "https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases/$RELEASE_ID/assets?name=$(basename $file)" - done diff --git a/docs/gitea-actions-guide.md b/docs/gitea-actions-guide.md index ec59e39..1dd1362 100644 --- a/docs/gitea-actions-guide.md +++ b/docs/gitea-actions-guide.md @@ -241,55 +241,12 @@ on: - v* jobs: - create-docker-image: - runs-on: ubuntu-latest - container: - image: docker:28.3.2-dind - steps: - - name: Checkout repository - run: | - # Install git - apk add --no-cache git - - echo "=== GitHub Variables ===" - echo "github.ref = ${{ github.ref }}" - echo "github.ref_name = ${{ github.ref_name }}" - echo "github.sha = ${{ github.sha }}" - echo "github.repository = ${{ github.repository }}" - echo "========================" - git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea - cd hello_gitea - git checkout ${{ github.ref }} - - - name: Setup Docker Buildx - run: | - # Docker is already installed in docker:dind image - docker --version - - # Setup Docker Buildx for multi-platform builds - docker buildx create --use - docker buildx inspect --bootstrap - - - name: Login to Docker Hub - run: | - echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin - - - name: Build multi-platform Docker images - run: | - cd hello_gitea - # Build multi-platform images using buildx - docker buildx build \ - --platform linux/amd64,linux/arm64 \ - --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:${{ github.ref_name }} \ - --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:latest \ - --push \ - . - create-release: runs-on: ubuntu-latest container: - image: golang:1.21 - needs: create-docker-image + # image: golang:1.21 + image: ${{ secrets.DOCKERHUB_USERNAME }}/my-build-golang-runner:latest + needs: create-release-branch steps: - name: Checkout repository run: | @@ -300,7 +257,7 @@ jobs: - name: Setup Go run: | # Install jq for JSON parsing - apt-get update && apt-get install -y jq + # apt-get update && apt-get install -y jq git --version go version jq --version @@ -357,40 +314,121 @@ jobs: --data-binary @$file \ "https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases/$RELEASE_ID/assets?name=$(basename $file)" done + + create-docker-image: + runs-on: ubuntu-latest + container: + image: docker:28.3.2-dind + needs: create-release + steps: + - name: Checkout repository + run: | + # Install git + apk add --no-cache git + + echo "=== GitHub Variables ===" + echo "github.ref = ${{ github.ref }}" + echo "github.ref_name = ${{ github.ref_name }}" + echo "github.sha = ${{ github.sha }}" + echo "github.repository = ${{ github.repository }}" + echo "========================" + git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea + cd hello_gitea + git checkout ${{ github.ref }} + + - name: Setup Docker Buildx + run: | + # Docker is already installed in docker:dind image + docker --version + + # Setup Docker Buildx for multi-platform builds + docker buildx create --use + docker buildx inspect --bootstrap + + - name: Login to Docker Hub + run: | + echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + + - name: Build multi-platform Docker images + run: | + cd hello_gitea + # Build multi-platform images using buildx + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:${{ github.ref_name }} \ + --tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:latest \ + --push \ + . + + update-to-release-branch: + runs-on: ubuntu-latest + container: + image: docker:28.3.2-dind + needs: create-docker-image + steps: + - name: Create Release Branch + run: | + echo "=== GitHub Variables ===" + echo "github.ref = ${{ github.ref }}" + echo "github.ref_name = ${{ github.ref_name }}" + echo "github.sha = ${{ github.sha }}" + echo "github.repository = ${{ github.repository }}" + echo "DOCKERHUB_USERNAME = ${{ secrets.DOCKERHUB_USERNAME }}" + echo "DOCKERHUB_TOKEN = ${{ secrets.DOCKERHUB_TOKEN }}" + echo "GITEATOKEN = ${{ secrets.GITEATOKEN }}" + echo "========================" + # Clone repository + echo "Cloning repository..." + git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea + cd hello_gitea + + # Configure git + echo "Configuring git..." + git config user.email "info@direct-dev.ru" + git config user.name "Direct-Dev-Robot" + + # Check if release branch exists + echo "Checking if release branch exists..." + if git ls-remote --heads origin release | grep -q release; then + echo "Release branch exists, checking out..." + git checkout release + echo "release branch exists - pulling release branch..." + git pull origin release + else + echo "release branch does not exist - creating new release branch..." + git checkout -b release + fi + + # Reset to the tag commit + echo "Resetting to the tag commit ${{ github.ref_name }} ..." + git reset --hard ${{ github.ref_name }} + + # Push changes to release branch + echo "Pushing changes to release branch..." + git push origin release --force ``` ### Разберемся как работает workflow **Триггеры:** -- Workflow запускается при создании тега, начинающегося с `v*` (например, `v1.0.0`) +- Workflow запускается при пуше в Gitea тега, начинающегося с `v*` (например, `v1.1.29`) **Jobs:** -1 **create-docker-image:** - создание образов docker с нашим проектом +1 **create-release:** -- Используем Docker-in-Docker контейнер (image: docker:28.3.2-dind) -- Настраиваем Docker Buildx для мультиплатформенной сборки (docker buildx create --use docker buildx inspect --bootstrap) -- Авторизуемч в Docker Hub (echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin) -- Собирает образы для Linux AMD64 и ARM64 (docker buildx build \ ...) -- Публикует образы с тегом версии и `latest` (--push) - -чтобы авторизация сработала на докерхабе надо внести секреты DOCKERHUB_TOKEN, DOCKERHUB_USERNAME или вцелом для всей gitea в настройках или в настройках конкретного репозитория -я использовал докерхаб, но можно заморочиться и настроить работу с приватным репозиторием ... - -2 **create-release:** - -- Запускается после успешной сборки Docker образов -- Использует Go контейнер для сборки бинарников (image: golang:1.21) +- Запускается первым +- Использует контейнер собранный на базе golang:1.24 для сборки бинарников (image: ${{ secrets.DOCKERHUB_USERNAME }}/my-build-golang-runner:latest) - Собирает бинарники для всех платформ (Linux, Windows, macOS) - Создает архивы с бинарниками -- Создает релиз через Gitea API +- Создает релиз с именем текущей версии через Gitea API - Загружает бинарники как assets релиза -при каждом запуске данного job будет скачиваться jq и устанавливаться в контейнере, созданном на базе golang:1.21 +для работы данного job используется кастомный образ - если бы мы использовали просто golang:1.24, то при каждом запуске данного job необходимо было бы скачивать jq и устанавливаться в контейнере (возможно со временем что то еще потребовалось бы) ```yaml - - name: Setup Go + - name: Setup Go container run: | # Install jq for JSON parsing apt-get update && apt-get install -y jq @@ -399,7 +437,7 @@ jobs: jq --version ``` -**решение в лоб:** чтобы убрать эту повторяющуюся работу при каждом выполнении workflow надо сделать свой образ - например "${DOCKERHUB_USERNAME}"/my-build-golang-runner:latest +**решение в лоб:** применено, чтобы убрать эту повторяющуюся работу при каждом выполнении workflow - сделан свой образ - "${DOCKERHUB_USERNAME}"/my-build-golang-runner:latest ``` Dockerfile # базовый образ @@ -417,7 +455,7 @@ RUN apt-get update && \ CMD ["bash"] ``` -Cобрать его и запушить (желательно с мультиплатформенностью) на каком-то локальном АРМ (не раннере) +Сначала собрал его и запушил (желательно с мультиплатформенностью) на каком-то локальном АРМ (не раннере) ```bash #!/bin/bash @@ -430,7 +468,7 @@ docker buildx build \ . ``` -или сделать задачу для сборки на раннере `.gitea/workflows/build-builder.yaml` +решение рабочее но надо всегда иметь под рукой АРм с buildx или лучше автоматизировать все и сделать задачу для сборки на раннере `.gitea/workflows/build-builder.yaml` ```yaml name: Build Builder Docker Image @@ -492,6 +530,37 @@ jobs: эта задача будет запущена на ранере при пуше тега с префиксом `builder-` +2 **create-docker-image:** - создание образов docker с нашим проектом + +- Запускается только после успешного завершения `create-release` +- Используем Docker-in-Docker контейнер (image: docker:28.3.2-dind) +- Настраиваем Docker Buildx для мультиплатформенной сборки (docker buildx create --use docker buildx inspect --bootstrap) +- Авторизуемся в Docker Hub (echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin) +- Собираем образы для Linux AMD64 и ARM64 (команда docker buildx build \ ...) +- Публикуем образы с тегом версии и `latest` (опция --push команды docker buildx build ...) + +чтобы авторизация сработала на докерхабе надо внести секреты DOCKERHUB_TOKEN, DOCKERHUB_USERNAME или вцелом для всего инстанса gitea в настройках инстанса или в настройках конкретного репозитория +я использовал докерхаб, но можно заморочиться и настроить работу с приватным репозиторием ... + +Уже после ряда тестовых релизо выяснил, что запуски workflow `build.yaml` да собственно как и `build-builder.yaml` порождают на хосте раннера зависшие докер контейнеры buildx + +```text + +СONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +2a9ad63c5a31 moby/buildkit:buildx-stable-1 "buildkitd --allow-i…" 11 seconds ago Up 10 seconds buildx_buildkit_test-buldx0 +843eee192570 moby/buildkit:buildx-stable-1 "buildkitd --allow-i…" 22 minutes ago Up 22 minutes buildx_buildkit_modest_haibt0 + +``` + +Это происходит потому, что раннер запускает докер в докере контейнер также +docker run --privileged -it --rm -v /var/run/docker.sock:/var/run/docker.sock docker:28.3.2-dind sh +то есть пробрасывает хостовый сокет докер демона в контейнер и когда там выполняется `docker buildx create --use` контейнер запускается на хосте а не внутри docker:28.3.2-dind + +Со временем это может превратиться в утечку ресурсов + +Решения как минимум два - добавить параметр --name - `docker buildx create --name go-buildx --use` - тогда подхватится существующий контейнер или создастся новый. Второй способ удалять buildx `docker buildx rm --name go-buildx` + + ## Настройка секретов ### Необходимые секреты @@ -533,7 +602,7 @@ jobs: 1 **Проверим синтаксис workflow:** -ну если мы в ide то наверное все автоматом отформатировано +ну если мы в ide, то наверное все хорошо и уже автоматом отформатировано ... но тем не менее ... ```bash @@ -543,6 +612,8 @@ jobs: 2 **Протестируем сборку локально:** +пока ручное тестирование + ```bash # Сборка для текущей платформы go build -o hello-api main.go @@ -565,17 +636,20 @@ jobs: curl http://localhost:8080/healthz ``` +тут надо погонять curl по эндпойнтам, убедиться что приложение работает (пока тоже вручную) + ### Запуск Actions -1 **Создаем тег:** +1 **Создаем тег вручную или скриптом (`scripts/release-interactive.sh`):** ```bash git tag v1.1.20 git push origin v1.1.20 - # или скрипт - + # текст скрипта - запуск можно сделать через make + #release-interactive: + # @./scripts/release-interactive.sh #!/bin/bash @@ -596,7 +670,7 @@ jobs: echo "" # Запрашиваем новую версию - read -p "Введите новую версию (формат X.Y.Z): " VERSION + read -r -p "Введите новую версию (формат X.Y.Z): " VERSION # Проверяем, что версия не пустая if [ -z "$VERSION" ]; then @@ -616,7 +690,7 @@ jobs: echo " Текущая версия: $CURRENT_VERSION" echo " Новая версия: $VERSION" echo "" - read -p "Продолжить? (y/N): " CONFIRM + read -r -p "Продолжить? (y/N): " CONFIRM if [[ ! $CONFIRM =~ ^[Yy]$ ]]; then echo "❌ Релиз отменен" @@ -671,6 +745,24 @@ jobs: echo "✅ Версия обновлена в main.go" + # Обновляем версию в makefile + echo "📝 Обновляем версию в makefile..." + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + sed -i '' "s/^VERSION=.*/VERSION=$VERSION/" makefile + else + # Linux + sed -i "s/^VERSION=.*/VERSION=$VERSION/" makefile + fi + + # Проверяем, что изменение применилось + if ! grep -q "^VERSION=$VERSION" makefile; then + echo "Ошибка: Не удалось обновить версию в makefile" + exit 1 + fi + + echo "✅ Версия обновлена в makefile" + # Выполняем git команды echo "📦 Добавляем изменения в git..." git add . @@ -688,6 +780,7 @@ jobs: echo "🎉 Релиз v$VERSION успешно завершен!" echo "📋 Выполненные действия:" echo " - Обновлена версия в main.go" + echo " - Обновлена версия в makefile" echo " - Создан коммит с сообщением 'Release v$VERSION'" echo " - Создан тег v$VERSION" echo " - Изменения отправлены в удаленный репозиторий" @@ -704,12 +797,7 @@ jobs: После успешного выполнения: -1 **Docker образы** будут опубликованы в Docker Hub: - -- `username/hello-api:v1.1.20` -- `username/hello-api:latest` - -2 **Релиз** будет создан в Gitea с бинарниками: +1 **Релиз** будет создан в Gitea с бинарниками: - `hello-api-linux-amd64.tar.gz` - `hello-api-linux-arm64.tar.gz` @@ -717,6 +805,13 @@ jobs: - `hello-api-darwin-amd64.tar.gz` - `hello-api-darwin-arm64.tar.gz` +2 **Docker образы** будут опубликованы в Docker Hub: + +- `username/hello-api:v1.1.20` +- `username/hello-api:latest` + +3 **В ветке relese** появится новый коммит - на него можно, например, настроить деплой ArgoCD/flux в кластере k3s + ## Мониторинг и отладка ### Просмотр логов diff --git a/main.go b/main.go index 76d4334..962ec1b 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" ) -const version = "1.0.28" +const version = "1.0.30" func main() { // Set Gin mode diff --git a/makefile b/makefile index 69a52d7..5badd1b 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ BIN_DIR=bin APP_NAME=hello-api -VERSION=1.0.28 +VERSION=1.0.30 build: mkdir -p $(BIN_DIR) diff --git a/scripts/release-interactive.sh b/scripts/release-interactive.sh index 62ea25d..5296c48 100755 --- a/scripts/release-interactive.sh +++ b/scripts/release-interactive.sh @@ -17,7 +17,7 @@ get_version_interactive() { echo "" # Запрашиваем новую версию - read -p "Введите новую версию (формат X.Y.Z): " VERSION + read -r -p "Введите новую версию (формат X.Y.Z): " VERSION # Проверяем, что версия не пустая if [ -z "$VERSION" ]; then