Merge pull request #6 #106
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD | |
| on: | |
| push: | |
| branches: [develop, main] | |
| tags: ['v*'] | |
| jobs: | |
| detect-changes: | |
| runs-on: [self-hosted] | |
| outputs: | |
| web: ${{ steps.changes.outputs.web }} | |
| server: ${{ steps.changes.outputs.server }} | |
| tag: ${{ steps.meta.outputs.tag }} | |
| env_name: ${{ steps.meta.outputs.env_name }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 2 | |
| - id: changes | |
| run: | | |
| # На тегах и main всегда собираем всё | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]] || [[ "$GITHUB_REF" == refs/heads/main ]]; then | |
| echo "web=true" >> "$GITHUB_OUTPUT" | |
| echo "server=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| DIFF=$(git diff --name-only HEAD~1) | |
| # Изменение корневого package.json (версия) пересобирает всё | |
| if echo "$DIFF" | grep -q '^package\.json$'; then | |
| echo "web=true" >> "$GITHUB_OUTPUT" | |
| echo "server=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if echo "$DIFF" | grep -qE '^(apps/web/|packages/)'; then | |
| echo "web=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "web=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$DIFF" | grep -q '^apps/server/'; then | |
| echo "server=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "server=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - id: meta | |
| run: | | |
| # Определяем Docker-тег и окружение деплоя | |
| # develop → :latest + env=beta | |
| # main → :stable + env=prod | |
| # v* → :version + env= (no deploy) | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]]; then | |
| echo "tag=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT" | |
| echo "env_name=" >> "$GITHUB_OUTPUT" | |
| elif [[ "$GITHUB_REF" == refs/heads/main ]]; then | |
| echo "tag=stable" >> "$GITHUB_OUTPUT" | |
| echo "env_name=prod" >> "$GITHUB_OUTPUT" | |
| elif [[ "$GITHUB_REF" == refs/heads/develop ]]; then | |
| echo "tag=latest" >> "$GITHUB_OUTPUT" | |
| echo "env_name=beta" >> "$GITHUB_OUTPUT" | |
| fi | |
| lint: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.web == 'true' | |
| runs-on: [self-hosted] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm lint | |
| lint-server: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.server == 'true' | |
| runs-on: [self-hosted] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: apps/server/go.mod | |
| cache: false | |
| - uses: golangci/golangci-lint-action@v7 | |
| with: | |
| version: v2.10.1 | |
| working-directory: apps/server | |
| test-server: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.server == 'true' | |
| runs-on: [self-hosted] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: apps/server/go.mod | |
| cache: false | |
| - name: Run Go tests | |
| working-directory: apps/server | |
| run: go test ./... | |
| build-web: | |
| needs: [detect-changes, lint] | |
| if: needs.detect-changes.outputs.web == 'true' | |
| runs-on: [self-hosted] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Build image | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| docker build -f apps/web/Dockerfile \ | |
| -t sdsandbox-web:$TAG \ | |
| . | |
| - name: Push to Nexus | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| echo "${{ secrets.NEXUS_PASSWORD }}" | docker login "${{ secrets.NEXUS_URL }}" -u "${{ secrets.NEXUS_USERNAME }}" --password-stdin | |
| docker tag sdsandbox-web:$TAG ${{ secrets.NEXUS_URL }}/sdsandbox-web:$TAG | |
| docker push ${{ secrets.NEXUS_URL }}/sdsandbox-web:$TAG | |
| - name: Push to Docker Hub | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin | |
| docker tag sdsandbox-web:$TAG khorost/sdsandbox-web:$TAG | |
| docker push khorost/sdsandbox-web:$TAG | |
| - name: Deploy to prod | |
| if: needs.detect-changes.outputs.env_name == 'prod' | |
| run: | | |
| RESPONSE=$(curl -s "${{ secrets.UPDATER_URL }}/update/sdsandbox-web-live/${{ secrets.UPDATER_KEY }}?async=1") | |
| echo "Response: $RESPONSE" | |
| SUBMITTED=$(echo "$RESPONSE" | jq -r '.submitted') | |
| if [ "$SUBMITTED" != "ok" ]; then | |
| echo "Updater call failed, submitted=$SUBMITTED" | |
| exit 1 | |
| fi | |
| - name: Deploy to beta | |
| if: needs.detect-changes.outputs.env_name == 'beta' | |
| run: | | |
| RESPONSE=$(curl -s "${{ secrets.UPDATER_URL }}/update/sdsandbox-web-beta/${{ secrets.UPDATER_KEY }}?async=1") | |
| echo "Response: $RESPONSE" | |
| SUBMITTED=$(echo "$RESPONSE" | jq -r '.submitted') | |
| if [ "$SUBMITTED" != "ok" ]; then | |
| echo "Updater call failed, submitted=$SUBMITTED" | |
| exit 1 | |
| fi | |
| build-server: | |
| needs: [detect-changes, lint-server, test-server] | |
| if: needs.detect-changes.outputs.server == 'true' | |
| runs-on: [self-hosted] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Build image | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| docker build -f apps/server/Dockerfile \ | |
| --build-arg VERSION=$TAG \ | |
| --build-arg COMMIT=${GITHUB_SHA::8} \ | |
| -t sdsandbox-server:$TAG \ | |
| apps/server | |
| - name: Push to Nexus | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| echo "${{ secrets.NEXUS_PASSWORD }}" | docker login "${{ secrets.NEXUS_URL }}" -u "${{ secrets.NEXUS_USERNAME }}" --password-stdin | |
| docker tag sdsandbox-server:$TAG ${{ secrets.NEXUS_URL }}/sdsandbox-server:$TAG | |
| docker push ${{ secrets.NEXUS_URL }}/sdsandbox-server:$TAG | |
| - name: Push to Docker Hub | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| TAG=${{ needs.detect-changes.outputs.tag }} | |
| echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin | |
| docker tag sdsandbox-server:$TAG khorost/sdsandbox-server:$TAG | |
| docker push khorost/sdsandbox-server:$TAG | |
| - name: Deploy to prod | |
| if: needs.detect-changes.outputs.env_name == 'prod' | |
| run: | | |
| RESPONSE=$(curl -s "${{ secrets.UPDATER_URL }}/update/sdsandbox-api-live/${{ secrets.UPDATER_KEY }}?async=1") | |
| echo "Response: $RESPONSE" | |
| SUBMITTED=$(echo "$RESPONSE" | jq -r '.submitted') | |
| if [ "$SUBMITTED" != "ok" ]; then | |
| echo "Updater call failed, submitted=$SUBMITTED" | |
| exit 1 | |
| fi | |
| - name: Deploy to beta | |
| if: needs.detect-changes.outputs.env_name == 'beta' | |
| run: | | |
| RESPONSE=$(curl -s "${{ secrets.UPDATER_URL }}/update/sdsandbox-api-beta/${{ secrets.UPDATER_KEY }}?async=1") | |
| echo "Response: $RESPONSE" | |
| SUBMITTED=$(echo "$RESPONSE" | jq -r '.submitted') | |
| if [ "$SUBMITTED" != "ok" ]; then | |
| echo "Updater call failed, submitted=$SUBMITTED" | |
| exit 1 | |
| fi |