BREAKING CHANGE: Bump verwion to 1.0 #1
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 and Release | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| lint-backend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.23.3" | |
| - name: Cache Go modules | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/go/pkg/mod | |
| ~/.cache/go-build | |
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go- | |
| - name: Install golangci-lint | |
| run: | | |
| curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.60.3 | |
| echo "$(go env GOPATH)/bin" >> $GITHUB_PATH | |
| - name: Install swag for swagger generation | |
| run: go install github.com/swaggo/swag/cmd/[email protected] | |
| - name: Generate swagger docs | |
| run: | | |
| cd backend | |
| swag init -d . -g cmd/main.go -o swagger | |
| - name: Run golangci-lint | |
| run: | | |
| cd backend | |
| golangci-lint run | |
| - name: Verify go mod tidy | |
| run: | | |
| cd backend | |
| go mod tidy | |
| git diff --exit-code go.mod go.sum || (echo "go mod tidy made changes, please run 'go mod tidy' and commit the changes" && exit 1) | |
| lint-frontend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: | | |
| cd frontend | |
| npm ci | |
| - name: Check if prettier was run | |
| run: | | |
| cd frontend | |
| npm run format | |
| git diff --exit-code || (echo "Prettier made changes, please run 'npm run format' and commit the changes" && exit 1) | |
| - name: Check if linter was run | |
| run: | | |
| cd frontend | |
| npm run lint | |
| determine-version: | |
| runs-on: ubuntu-latest | |
| needs: [lint-backend, lint-frontend] | |
| if: ${{ !contains(github.event.head_commit.message, '[skip-release]') }} | |
| outputs: | |
| should_release: ${{ steps.version_bump.outputs.should_release }} | |
| new_version: ${{ steps.version_bump.outputs.new_version }} | |
| bump_type: ${{ steps.version_bump.outputs.bump_type }} | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Install semver | |
| run: npm install -g semver | |
| - name: Get current version | |
| id: current_version | |
| run: | | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| echo "current_version=${LATEST_TAG#v}" >> $GITHUB_OUTPUT | |
| echo "Current version: ${LATEST_TAG#v}" | |
| - name: Analyze commits and determine version bump | |
| id: version_bump | |
| run: | | |
| CURRENT_VERSION="${{ steps.current_version.outputs.current_version }}" | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| # Get commits since last tag | |
| if [ "$LATEST_TAG" = "v0.0.0" ]; then | |
| COMMITS=$(git log --pretty=format:"%s" --no-merges) | |
| else | |
| COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"%s" --no-merges) | |
| fi | |
| echo "Analyzing commits:" | |
| echo "$COMMITS" | |
| # Initialize flags | |
| HAS_FEATURE=false | |
| HAS_FIX=false | |
| HAS_BREAKING=false | |
| # Analyze each commit | |
| while IFS= read -r commit; do | |
| if [[ "$commit" =~ ^FEATURE ]]; then | |
| HAS_FEATURE=true | |
| echo "Found FEATURE commit: $commit" | |
| elif [[ "$commit" =~ ^FIX ]]; then | |
| HAS_FIX=true | |
| echo "Found FIX commit: $commit" | |
| elif [[ "$commit" =~ ^REFACTOR ]]; then | |
| HAS_FIX=true # Treat refactor as patch | |
| echo "Found REFACTOR commit: $commit" | |
| fi | |
| # Check for breaking changes | |
| if [[ "$commit" =~ BREAKING[[:space:]]CHANGE ]] || [[ "$commit" =~ "!" ]]; then | |
| HAS_BREAKING=true | |
| echo "Found BREAKING CHANGE: $commit" | |
| fi | |
| done <<< "$COMMITS" | |
| # Determine version bump | |
| if [ "$HAS_BREAKING" = true ]; then | |
| BUMP_TYPE="major" | |
| elif [ "$HAS_FEATURE" = true ]; then | |
| BUMP_TYPE="minor" | |
| elif [ "$HAS_FIX" = true ]; then | |
| BUMP_TYPE="patch" | |
| else | |
| BUMP_TYPE="none" | |
| fi | |
| echo "bump_type=$BUMP_TYPE" >> $GITHUB_OUTPUT | |
| if [ "$BUMP_TYPE" != "none" ]; then | |
| NEW_VERSION=$(npx semver -i $BUMP_TYPE $CURRENT_VERSION) | |
| echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| echo "New version will be: $NEW_VERSION" | |
| else | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| echo "No version bump needed" | |
| fi | |
| build-only: | |
| runs-on: ubuntu-latest | |
| needs: [lint-backend, lint-frontend] | |
| if: ${{ contains(github.event.head_commit.message, '[skip-release]') }} | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU (enables multi-arch emulation) | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build and push SHA-only tags | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: | | |
| rostislavdugin/postgresus:latest | |
| rostislavdugin/postgresus:${{ github.sha }} | |
| build-and-push: | |
| runs-on: ubuntu-latest | |
| needs: [determine-version] | |
| if: ${{ needs.determine-version.outputs.should_release == 'true' }} | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| - name: Set up QEMU (enables multi-arch emulation) | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build and push with version tags | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: | | |
| rostislavdugin/postgresus:latest | |
| rostislavdugin/postgresus:v${{ needs.determine-version.outputs.new_version }} | |
| rostislavdugin/postgresus:${{ github.sha }} | |
| - name: Update Docker Hub description | |
| uses: peter-evans/dockerhub-description@v4 | |
| continue-on-error: true | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_PASSWORD }} | |
| repository: rostislavdugin/postgresus | |
| short-description: "Free PostgreSQL monitoring & backup solution with multi-storage support" | |
| readme-filepath: ./README.md | |
| release: | |
| runs-on: ubuntu-latest | |
| needs: [determine-version, build-and-push] | |
| if: ${{ needs.determine-version.outputs.should_release == 'true' }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| NEW_VERSION="${{ needs.determine-version.outputs.new_version }}" | |
| LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") | |
| # Get commits since last tag | |
| if [ "$LATEST_TAG" = "v0.0.0" ]; then | |
| COMMITS=$(git log --pretty=format:"%s|%H|%an|%ad" --date=short --no-merges) | |
| else | |
| COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"%s|%H|%an|%ad" --date=short --no-merges) | |
| fi | |
| # Create changelog | |
| CHANGELOG="# Changelog\n\n## [${NEW_VERSION}] - $(date +%Y-%m-%d)\n\n" | |
| # Group commits by type and area | |
| FEATURES="" | |
| FIXES="" | |
| REFACTORS="" | |
| while IFS= read -r line; do | |
| if [ -n "$line" ]; then | |
| COMMIT_MSG=$(echo "$line" | cut -d'|' -f1) | |
| COMMIT_HASH=$(echo "$line" | cut -d'|' -f2) | |
| SHORT_HASH=${COMMIT_HASH:0:7} | |
| # Parse commit message format: TYPE (area): description | |
| if [[ "$COMMIT_MSG" == FEATURE* ]]; then | |
| TEMP="${COMMIT_MSG#FEATURE}" | |
| TEMP="${TEMP#"${TEMP%%[![:space:]]*}"}" | |
| if [[ "$TEMP" == \(* ]]; then | |
| AREA=$(echo "$TEMP" | sed 's/^(\([^)]*\)).*/\1/') | |
| DESC=$(echo "$TEMP" | sed 's/^([^)]*):[[:space:]]*//') | |
| FEATURES="${FEATURES}- **${AREA}**: ${DESC} ([${SHORT_HASH}](https://github.com/${{ github.repository }}/commit/${COMMIT_HASH}))\n" | |
| fi | |
| elif [[ "$COMMIT_MSG" == FIX* ]]; then | |
| TEMP="${COMMIT_MSG#FIX}" | |
| TEMP="${TEMP#"${TEMP%%[![:space:]]*}"}" | |
| if [[ "$TEMP" == \(* ]]; then | |
| AREA=$(echo "$TEMP" | sed 's/^(\([^)]*\)).*/\1/') | |
| DESC=$(echo "$TEMP" | sed 's/^([^)]*):[[:space:]]*//') | |
| FIXES="${FIXES}- **${AREA}**: ${DESC} ([${SHORT_HASH}](https://github.com/${{ github.repository }}/commit/${COMMIT_HASH}))\n" | |
| fi | |
| elif [[ "$COMMIT_MSG" == REFACTOR* ]]; then | |
| TEMP="${COMMIT_MSG#REFACTOR}" | |
| TEMP="${TEMP#"${TEMP%%[![:space:]]*}"}" | |
| if [[ "$TEMP" == \(* ]]; then | |
| AREA=$(echo "$TEMP" | sed 's/^(\([^)]*\)).*/\1/') | |
| DESC=$(echo "$TEMP" | sed 's/^([^)]*):[[:space:]]*//') | |
| REFACTORS="${REFACTORS}- **${AREA}**: ${DESC} ([${SHORT_HASH}](https://github.com/${{ github.repository }}/commit/${COMMIT_HASH}))\n" | |
| fi | |
| fi | |
| fi | |
| done <<< "$COMMITS" | |
| # Build changelog sections | |
| if [ -n "$FEATURES" ]; then | |
| CHANGELOG="${CHANGELOG}### ✨ Features\n${FEATURES}\n" | |
| fi | |
| if [ -n "$FIXES" ]; then | |
| CHANGELOG="${CHANGELOG}### 🐛 Bug Fixes\n${FIXES}\n" | |
| fi | |
| if [ -n "$REFACTORS" ]; then | |
| CHANGELOG="${CHANGELOG}### 🔨 Refactoring\n${REFACTORS}\n" | |
| fi | |
| # Add Docker image info | |
| CHANGELOG="${CHANGELOG}### 🐳 Docker\n" | |
| CHANGELOG="${CHANGELOG}- **Image**: \`rostislavdugin/postgresus:v${NEW_VERSION}\`\n" | |
| CHANGELOG="${CHANGELOG}- **Platforms**: linux/amd64, linux/arm64\n\n" | |
| # Set output for GitHub release | |
| { | |
| echo 'changelog<<EOF' | |
| echo -e "$CHANGELOG" | |
| echo EOF | |
| } >> $GITHUB_OUTPUT | |
| - name: Create GitHub Release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: v${{ needs.determine-version.outputs.new_version }} | |
| release_name: Release v${{ needs.determine-version.outputs.new_version }} | |
| body: ${{ steps.changelog.outputs.changelog }} | |
| draft: false | |
| prerelease: false |