Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ jobs:
create-release:
runs-on: ubuntu-latest
needs: build-and-deploy
if: needs.build-and-deploy.result == 'success' && github.event_name == 'push'
if: needs.build-and-deploy.result == 'success'
permissions:
contents: write

Expand Down
168 changes: 167 additions & 1 deletion .github/workflows/release-branch-creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,173 @@ jobs:
echo "- ℹ️ No changes needed (already up to date)" >> $GITHUB_STEP_SUMMARY
fi

# JOB 2: Bump develop branch version (only for releases, not hotfixes)
# JOB 2: Create PR from release/hotfix branch to main
create-main-pr:
if: github.event_name == 'create' && github.event.ref_type == 'branch' && (startsWith(github.event.ref, 'release/') || startsWith(github.event.ref, 'hotfix/'))
needs: release-branch-setup
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Analyze branch and version
id: version_info
run: |
BRANCH_NAME="${{ github.event.ref }}"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT

if [[ $BRANCH_NAME == release/* ]]; then
VERSION=$(echo $BRANCH_NAME | sed 's/release\///')
TYPE="release"
PR_TITLE="release: $VERSION"
elif [[ $BRANCH_NAME == hotfix/* ]]; then
VERSION=$(echo $BRANCH_NAME | sed 's/hotfix\///')
TYPE="hotfix"
PR_TITLE="fix: $VERSION"
fi

# Ensure version starts with 'v'
if [[ ! $VERSION == v* ]]; then
VERSION="v$VERSION"
fi

echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "type=$TYPE" >> $GITHUB_OUTPUT
echo "pr_title=$PR_TITLE" >> $GITHUB_OUTPUT
echo "clean_version=$(echo $VERSION | sed 's/^v//')" >> $GITHUB_OUTPUT

- name: Check for existing PR to main
id: check_existing_pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="${{ steps.version_info.outputs.branch_name }}"

# Check if there's already a PR from this branch to main
EXISTING_PRS=$(gh pr list --head "$BRANCH_NAME" --base main --state open --json number,title)

if [ "$(echo "$EXISTING_PRS" | jq '. | length')" -gt 0 ]; then
echo "⚠️ Found existing PR from $BRANCH_NAME to main:"
echo "$EXISTING_PRS" | jq -r '.[] | "#\(.number): \(.title)"'
echo "skip_pr=true" >> $GITHUB_OUTPUT

PR_NUMBER=$(echo "$EXISTING_PRS" | jq -r '.[0].number')
echo "existing_pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "✅ No existing PR found from $BRANCH_NAME to main"
echo "skip_pr=false" >> $GITHUB_OUTPUT
fi

- name: Create required labels if they don't exist
if: steps.check_existing_pr.outputs.skip_pr == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🏷️ Ensuring required labels exist..."

TYPE="${{ steps.version_info.outputs.type }}"

# Create labels if they don't exist
gh label create "auto-generated" --description "Automatically generated by GitHub Actions" --color "bfdadc" || echo "Label 'auto-generated' already exists"
gh label create "$TYPE" --description "$TYPE branch related" --color "d73a4a" || echo "Label '$TYPE' already exists"
gh label create "ready-to-merge" --description "Ready to be merged" --color "0e8a16" || echo "Label 'ready-to-merge' already exists"

echo "✅ Label creation completed"

- name: Create PR to main branch
if: steps.check_existing_pr.outputs.skip_pr == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="${{ steps.version_info.outputs.branch_name }}"
VERSION="${{ steps.version_info.outputs.version }}"
TYPE="${{ steps.version_info.outputs.type }}"
PR_TITLE="${{ steps.version_info.outputs.pr_title }}"
CLEAN_VERSION="${{ steps.version_info.outputs.clean_version }}"

# Build PR body
if [[ "$TYPE" == "release" ]]; then
PR_BODY="## Summary
$TYPE $VERSION ready for merge to main branch.

## Changes
- New features and improvements from develop branch
- Version bumped to $CLEAN_VERSION
- Updated changelog and documentation
- All tests passing and code reviewed

## Deployment
This $TYPE will be deployed to production after merge.

## Checklist
- [ ] All preparation tasks completed
- [ ] Tests are passing
- [ ] Documentation updated
- [ ] Ready for production deployment"
else
PR_BODY="## Summary
$TYPE $VERSION ready for merge to main branch.

## Changes
- Critical bug fixes
- Version bumped to $CLEAN_VERSION
- Updated changelog
- Hotfix tested and verified

## Deployment
This $TYPE will be deployed to production immediately after merge.

## Checklist
- [ ] Hotfix verified and tested
- [ ] Tests are passing
- [ ] Ready for immediate production deployment"
fi

# Create PR to main
gh pr create \
--base main \
--head "$BRANCH_NAME" \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--label "auto-generated" \
--label "$TYPE" \
--label "ready-to-merge"

echo "✅ Created PR from $BRANCH_NAME to main"

- name: Create main PR summary
run: |
BRANCH_NAME="${{ steps.version_info.outputs.branch_name }}"
VERSION="${{ steps.version_info.outputs.version }}"
TYPE="${{ steps.version_info.outputs.type }}"

echo "## 🎯 Main Branch PR" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Branch**: \`$BRANCH_NAME\`" >> $GITHUB_STEP_SUMMARY
echo "**Target**: main" >> $GITHUB_STEP_SUMMARY
echo "**Version**: $VERSION" >> $GITHUB_STEP_SUMMARY
echo "**Type**: $TYPE" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [[ "${{ steps.check_existing_pr.outputs.skip_pr }}" == "true" ]]; then
echo "**Status**: ⚠️ Skipped - PR already exists (#${{ steps.check_existing_pr.outputs.existing_pr_number }})" >> $GITHUB_STEP_SUMMARY
else
echo "**Status**: ✅ PR created successfully" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Actions Completed" >> $GITHUB_STEP_SUMMARY
echo "- 🎯 Created PR from \`$BRANCH_NAME\` to \`main\`" >> $GITHUB_STEP_SUMMARY
echo "- 🏷️ Applied appropriate labels" >> $GITHUB_STEP_SUMMARY
echo "- 📋 Added $TYPE checklist to PR description" >> $GITHUB_STEP_SUMMARY
fi

# JOB 3: Bump develop branch version (only for releases, not hotfixes)
bump-develop-version:
if: github.event_name == 'create' && github.event.ref_type == 'branch' && startsWith(github.event.ref, 'release/')
needs: release-branch-setup
Expand Down
12 changes: 11 additions & 1 deletion .version-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ release_process:
# Specify which files contain version information that should be updated
version_files:
- path: "cmd/main.go"
pattern: '@version\s+[\d\.]+'
pattern: '@version\s+[0-9]+\.[0-9]+\.[0-9]+'
replacement: '@version\t\t{version}'
description: "Swagger API version annotation"

Expand All @@ -71,6 +71,16 @@ version_files:
description: "Go module version (major only)"
when: "major_version_only"

- path: "internal/handler/covid_handler_test.go"
pattern: 'assert\.Equal\(t, "[0-9]+\.[0-9]+\.[0-9]+", [^)]*\["version"\]\)'
replacement: 'assert.Equal(t, "{version}", $1["version"])'
description: "Test version assertions"

- path: "internal/handler/covid_handler_test.go"
pattern: 'assert\.Equal\(t, "[0-9]+\.[0-9]+\.[0-9]+", data\["version"\]\)'
replacement: 'assert.Equal(t, "{version}", data["version"])'
description: "Health check test version assertion"

# Examples of usage:
#
# For planning a major version:
Expand Down
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0




## [v2.4.0] - 2025-09-15

### Added

- Configure deploy workflow for minimal production build (6.1mb) ([1d362189](https://github.com/banua-coder/pico-api-go/commit/1d362189e56fe7e7cea6b616593944761d1fdbbd))
- Optimize binary size with conditional swagger compilation ([64a56304](https://github.com/banua-coder/pico-api-go/commit/64a56304257db60a1e6db0561431701b9ecd57c9))
- Enhance ci with intelligent testing and coverage thresholds ([3058e376](https://github.com/banua-coder/pico-api-go/commit/3058e37690ea612eaa50aa4fa401cb2b366db931))
- Enhance release workflow with swagger regeneration and script organization ([cf94c807](https://github.com/banua-coder/pico-api-go/commit/cf94c807fe32b6970da58e527dbb68285628a3df))
- Simplify changelog generator and remove unnecessary complexity ([fc609bb7](https://github.com/banua-coder/pico-api-go/commit/fc609bb75f535ca6b8962886146eda655c5d894a))

### Fixed

- Exclude test files from golangci-lint to resolve mock interface issues ([d77e2c0c](https://github.com/banua-coder/pico-api-go/commit/d77e2c0cbe5004d33c35fec60f1e16a24983689c))
- Add golangci-lint configuration to resolve test file issues ([73b1e516](https://github.com/banua-coder/pico-api-go/commit/73b1e516277da92c5b65411f4a1b15b2ad163f81))
- Explicitly reference embedded db methods to resolve linter issues ([f86a70b1](https://github.com/banua-coder/pico-api-go/commit/f86a70b1736cc654841f4d8c3639296f0bea1b21))
- Resolve golangci-lint version compatibility issue in ci ([86872eec](https://github.com/banua-coder/pico-api-go/commit/86872eeca96a5e13920181a6dbfaec71ea7dc397))
- Resolve ci failures - integration tests and code formatting ([1f26b10f](https://github.com/banua-coder/pico-api-go/commit/1f26b10f03fa297c734c27b119db04fbf55e4d51))
- Remove redundant province data from latest_case in province list api ([00d63ebc](https://github.com/banua-coder/pico-api-go/commit/00d63ebc908a3cfcd2484a6d64aaa1fd4f402a2e))
- Implement config-based version management system ([3a68d854](https://github.com/banua-coder/pico-api-go/commit/3a68d85496d8bf3fbfd3ea44fae5dfc515f1b21c))
- Resolve workflow duplicates and conflicts ([2b756609](https://github.com/banua-coder/pico-api-go/commit/2b756609e3cb5701496ca699af64a1d22f083f36))
- Simplify workflows and restore working deploy.yml ([547f4556](https://github.com/banua-coder/pico-api-go/commit/547f45566a4f89d91ca4b15a595c784d0dbafe83))
- Fix generate changelog script (script) ([9ab39f0f](https://github.com/banua-coder/pico-api-go/commit/9ab39f0f40b73bad51fbc34b52645c97f2a25839))

### Documentation

- Update readme with latest project structure and ci features ([82cc7c9a](https://github.com/banua-coder/pico-api-go/commit/82cc7c9aa86c4518b15489d15c8a41689835fa25))

## [v2.3.0] - 2025-09-08

### Documentation
Expand Down
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func main() {
log.Fatalf("Failed to connect to database: %v", err)
}
defer func() {
if err := db.Close(); err != nil {
if err := db.DB.Close(); err != nil {
log.Printf("Error closing database connection: %v", err)
}
}()
Expand Down
6 changes: 6 additions & 0 deletions internal/handler/covid_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,19 @@ func (h *CovidHandler) GetProvinceCases(w http.ResponseWriter, r *http.Request)
// Parse query parameters
limit := utils.ParseIntQueryParam(r, "limit", 50)
offset := utils.ParseIntQueryParam(r, "offset", 0)
page := utils.ParseIntQueryParam(r, "page", 0)
all := utils.ParseBoolQueryParam(r, "all")
startDate := r.URL.Query().Get("start_date")
endDate := r.URL.Query().Get("end_date")

// Parse sort parameters (default: date ascending)
sortParams := utils.ParseSortParam(r, "date")

// Convert page to offset if page is specified (page-based pagination)
if page > 0 {
offset = (page - 1) * limit
}

// Validate pagination params
limit, offset = utils.ValidatePaginationParams(limit, offset)

Expand Down
15 changes: 8 additions & 7 deletions internal/repository/national_case_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package repository
import (
"database/sql"
"fmt"
"log"
"time"

"github.com/banua-coder/pico-api-go/internal/models"
Expand Down Expand Up @@ -48,7 +49,7 @@ func (r *nationalCaseRepository) GetAllSorted(sortParams utils.SortParams) ([]mo
}
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("Error closing rows: %v\n", err)
log.Printf("Error closing rows: %v", err)
}
}()

Expand Down Expand Up @@ -90,7 +91,7 @@ func (r *nationalCaseRepository) GetByDateRangeSorted(startDate, endDate time.Ti
}
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("Error closing rows: %v\n", err)
log.Printf("Error closing rows: %v", err)
}
}()

Expand Down Expand Up @@ -135,10 +136,10 @@ func (r *nationalCaseRepository) GetLatest() (*models.NationalCase, error) {
}

func (r *nationalCaseRepository) GetByDay(day int64) (*models.NationalCase, error) {
query := `SELECT id, day, date, positive, recovered, deceased,
query := `SELECT id, day, date, positive, recovered, deceased,
cumulative_positive, cumulative_recovered, cumulative_deceased,
rt, rt_upper, rt_lower
FROM national_cases
rt, rt_upper, rt_lower
FROM national_cases
WHERE day = ?`

var c models.NationalCase
Expand Down Expand Up @@ -183,7 +184,7 @@ func (r *nationalCaseRepository) GetAllPaginatedSorted(limit, offset int, sortPa
}
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("Error closing rows: %v\n", err)
log.Printf("Error closing rows: %v", err)
}
}()

Expand Down Expand Up @@ -235,7 +236,7 @@ func (r *nationalCaseRepository) GetByDateRangePaginatedSorted(startDate, endDat
}
defer func() {
if err := rows.Close(); err != nil {
fmt.Printf("Error closing rows: %v\n", err)
log.Printf("Error closing rows: %v", err)
}
}()

Expand Down
Loading