diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml deleted file mode 100644 index b71e0ba..0000000 --- a/.github/workflows/auto-release.yml +++ /dev/null @@ -1,191 +0,0 @@ -name: Auto Release - -on: - workflow_dispatch: - inputs: - version: - description: 'Version to release (e.g., v1.0.0)' - required: true - type: string - -permissions: - contents: write - -jobs: - create-release: - name: Create Tag and Release - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Validate version format - run: | - VERSION="${{ inputs.version }}" - if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then - echo "Error: Version must match format v1.2.3 or v1.2.3-beta.1" - exit 1 - fi - - - name: Check if tag exists - run: | - if git rev-parse "${{ inputs.version }}" >/dev/null 2>&1; then - echo "Error: Tag ${{ inputs.version }} already exists" - exit 1 - fi - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.24' - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-go-release-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-release- - - - name: Download dependencies - run: go mod download - - - name: Run tests - run: make test - - - name: Run linters - uses: golangci/golangci-lint-action@v9 - with: - version: v2.6.1 - args: --timeout=5m - - - name: Check code is clean - run: | - if [[ -n $(git status --porcelain) ]]; then - echo "Error: Working directory is not clean" - git status --short - exit 1 - fi - - - name: Generate changelog - id: changelog - run: | - PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - if [ -z "$PREV_TAG" ]; then - CHANGELOG=$(git log --oneline --decorate) - else - CHANGELOG=$(git log ${PREV_TAG}..HEAD --oneline --decorate) - fi - echo "CHANGELOG<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # Also output previous tag for release notes - echo "PREV_TAG=$PREV_TAG" >> $GITHUB_OUTPUT - - - name: Create CHANGELOG.md - run: | - VERSION="${{ inputs.version }}" - PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - DATE=$(date +%Y-%m-%d) - - # Create new changelog entry - { - echo "# Changelog" - echo "" - echo "All notable changes to this project will be documented in this file." - echo "" - echo "## [$VERSION] - $DATE" - echo "" - if [ -z "$PREV_TAG" ]; then - echo "### Initial Release" - echo "" - git log --oneline --decorate | sed 's/^/- /' - else - echo "### Changes since $PREV_TAG" - echo "" - git log ${PREV_TAG}..HEAD --oneline --decorate | sed 's/^/- /' - fi - echo "" - - # Append existing changelog if it exists - if [ -f CHANGELOG.md ]; then - tail -n +2 CHANGELOG.md - fi - } > CHANGELOG.md.new - - mv CHANGELOG.md.new CHANGELOG.md - - - name: Configure Git - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - - name: Commit CHANGELOG.md - run: | - git add CHANGELOG.md - git commit -m "chore: Update CHANGELOG.md for ${{ inputs.version }}" - - - name: Create and push tag - run: | - git tag -a "${{ inputs.version }}" -m "Release ${{ inputs.version }}" - git push origin "${{ inputs.version }}" - - - name: Create GitHub Release - uses: ncipollo/release-action@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ inputs.version }} - name: Release ${{ inputs.version }} - artifacts: "CHANGELOG.md" - body: | - # Release ${{ inputs.version }} - - ## Installation - - ```bash - go get github.com/xraph/vessel@${{ inputs.version }} - ``` - - Or for individual packages: - - ```bash - go get github.com/xraph/vessel/errs@${{ inputs.version }} - go get github.com/xraph/vessel/log@${{ inputs.version }} - ``` - - ## Changes - - ${{ steps.changelog.outputs.PREV_TAG != '' && format('Changes since {0}:', steps.changelog.outputs.PREV_TAG) || 'Initial release:' }} - - ``` - ${{ steps.changelog.outputs.CHANGELOG }} - ``` - - ## Documentation - - - [README](https://github.com/xraph/vessel/blob/${{ inputs.version }}/README.md) - - [errs Package](https://github.com/xraph/vessel/blob/${{ inputs.version }}/errs/README.md) - - [Go Package Documentation](https://pkg.go.dev/github.com/xraph/vessel@${{ inputs.version }}) - draft: false - prerelease: ${{ contains(inputs.version, '-') }} - - - name: Trigger pkg.go.dev update - run: | - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/@v/${{ inputs.version }}.info" || true - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/errs/@v/${{ inputs.version }}.info" || true - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/log/@v/${{ inputs.version }}.info" || true - - - name: Release Summary - run: | - echo "## ✅ Release ${{ inputs.version }} Created Successfully!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **Tag**: ${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY - echo "- **Release**: [View on GitHub](https://github.com/${{ github.repository }}/releases/tag/${{ inputs.version }})" >> $GITHUB_STEP_SUMMARY - echo "- **Package**: [View on pkg.go.dev](https://pkg.go.dev/github.com/xraph/vessel@${{ inputs.version }})" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c94d078..790c713 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,123 +2,18 @@ name: CI on: push: - branches: [ main, master, develop ] + branches: [main] pull_request: - branches: [ main, master, develop ] + branches: [main] -jobs: - test: - name: Test - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - go-version: ['1.22', '1.23', '1.24'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-${{ matrix.go-version }}- - - - name: Download dependencies - run: go mod download - - - name: Run tests - run: make test - - - name: Run tests with coverage (Linux only) - if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24' - run: make test-coverage - - - name: Upload coverage to Codecov - if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24' - uses: codecov/codecov-action@v4 - with: - file: ./coverage/coverage.out - flags: unittests - name: vessel-coverage - - lint: - name: Lint - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.24' - - - name: Run golangci-lint - uses: golangci/golangci-lint-action@v9 - with: - version: v2.6.1 - args: --timeout=5m +permissions: + contents: read + security-events: write - verify: - name: Verify - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.24' - - - name: Check formatting - run: | - if [ -n "$(gofmt -l .)" ]; then - echo "Code is not formatted. Run 'make fmt'" - gofmt -l . - exit 1 - fi - - - name: Run go vet - run: make vet - - - name: Check go.mod tidiness - run: | - go mod tidy - git diff --exit-code go.mod go.sum - - security: - name: Security - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.24' - - - name: Run gosec - run: | - go install github.com/securego/gosec/v2/cmd/gosec@latest - gosec -exclude=G115 -exclude-dir=vendor ./... - - - name: Run govulncheck - run: | - go install golang.org/x/vuln/cmd/govulncheck@latest - govulncheck ./... +jobs: + ci: + uses: xraph/workflows/.github/workflows/go-ci.yml@v1 + with: + go-versions: '["1.25","1.26"]' + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9394fb0..54b5076 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,39 +2,19 @@ name: CodeQL on: push: - branches: [ main, master, develop ] + branches: [main] pull_request: - branches: [ main, master, develop ] + branches: [main] schedule: - - cron: '0 0 * * 1' # Weekly on Monday at midnight + - cron: '0 0 * * 1' + +permissions: + actions: read + contents: read + security-events: write jobs: analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - - - name: Autobuild - uses: github/codeql-action/autobuild@v4 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: "/language:${{matrix.language}}" + uses: xraph/workflows/.github/workflows/codeql.yml@v1 + with: + go-version: '1.26' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eecdc09..3ce4cea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,140 +1,20 @@ name: Release on: - push: - tags: - - 'v*' + workflow_dispatch: + workflow_run: + workflows: ["CI"] + types: [completed] + branches: [main] permissions: contents: write + issues: write + pull-requests: write jobs: release: - name: Create Release - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.24' - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/go/pkg/mod - ~/.cache/go-build - key: ${{ runner.os }}-go-release-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-release- - - - name: Download dependencies - run: go mod download - - - name: Run tests - run: make test - - - name: Run linters - uses: golangci/golangci-lint-action@v9 - with: - version: v2.6.1 - args: --timeout=5m - - - name: Get version from tag - id: get_version - run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - - - name: Generate changelog - id: changelog - run: | - PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - if [ -z "$PREV_TAG" ]; then - CHANGELOG=$(git log --oneline --decorate) - else - CHANGELOG=$(git log ${PREV_TAG}..HEAD --oneline --decorate) - fi - echo "CHANGELOG<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create CHANGELOG.md for release - run: | - VERSION="${GITHUB_REF#refs/tags/}" - PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - DATE=$(date +%Y-%m-%d) - - { - echo "# Changelog for $VERSION" - echo "" - echo "Released: $DATE" - echo "" - if [ -z "$PREV_TAG" ]; then - echo "## Initial Release" - echo "" - git log --oneline --decorate | sed 's/^/- /' - else - echo "## Changes since $PREV_TAG" - echo "" - git log ${PREV_TAG}..HEAD --oneline --decorate | sed 's/^/- /' - fi - } > CHANGELOG-$VERSION.md - - - name: Create Release - uses: ncipollo/release-action@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ steps.get_version.outputs.VERSION }} - name: Release ${{ steps.get_version.outputs.VERSION }} - artifacts: "CHANGELOG-${{ steps.get_version.outputs.VERSION }}.md" - body: | - # Release ${{ steps.get_version.outputs.VERSION }} - - ## Installation - - ```bash - go get github.com/xraph/vessel@${{ steps.get_version.outputs.VERSION }} - ``` - - Or for individual packages: - - ```bash - go get github.com/xraph/vessel/errs@${{ steps.get_version.outputs.VERSION }} - go get github.com/xraph/vessel/log@${{ steps.get_version.outputs.VERSION }} - ``` - - ## Changes - - ``` - ${{ steps.changelog.outputs.CHANGELOG }} - ``` - - ## Documentation - - - [README](https://github.com/xraph/vessel/blob/${{ steps.get_version.outputs.VERSION }}/README.md) - - [errs Package](https://github.com/xraph/vessel/blob/${{ steps.get_version.outputs.VERSION }}/errs/README.md) - - [Go Package Documentation](https://pkg.go.dev/github.com/xraph/vessel@${{ steps.get_version.outputs.VERSION }}) - draft: false - prerelease: false - - notify: - name: Notify Release - needs: release - runs-on: ubuntu-latest - if: success() - - steps: - - name: Get version - id: get_version - run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - - - name: Trigger pkg.go.dev update - run: | - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/@v/${{ steps.get_version.outputs.VERSION }}.info" || true - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/errs/@v/${{ steps.get_version.outputs.VERSION }}.info" || true - curl -sSf "https://proxy.golang.org/github.com/xraph/vessel/log/@v/${{ steps.get_version.outputs.VERSION }}.info" || true \ No newline at end of file + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' + uses: xraph/workflows/.github/workflows/semantic-release.yml@v1 + with: + warm-go-proxy: true diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..3a91e5b --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,40 @@ +{ + "branches": ["main"], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { "type": "feat", "release": "minor" }, + { "type": "fix", "release": "patch" }, + { "type": "perf", "release": "patch" }, + { "type": "revert", "release": "patch" }, + { "type": "docs", "release": "patch" }, + { "type": "refactor", "release": "patch" }, + { "type": "chore", "release": false }, + { "type": "test", "release": false }, + { "type": "build", "release": false }, + { "type": "ci", "release": false }, + { "breaking": true, "release": "major" } + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { "preset": "conventionalcommits" } + ], + [ + "@semantic-release/changelog", + { "changelogFile": "CHANGELOG.md" } + ], + "@semantic-release/github", + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ] + ] +} diff --git a/constructor.go b/constructor.go index f83a417..4dbdb11 100644 --- a/constructor.go +++ b/constructor.go @@ -171,7 +171,7 @@ func analyzeResult(t reflect.Type, index int) (resultInfo, error) { // isInStruct checks if a type embeds vessel.In func isInStruct(t reflect.Type) bool { // Handle pointer types - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } @@ -195,7 +195,7 @@ func isInStruct(t reflect.Type) bool { // isOutStruct checks if a type embeds vessel.Out func isOutStruct(t reflect.Type) bool { // Handle pointer types - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } @@ -218,7 +218,7 @@ func isOutStruct(t reflect.Type) bool { // expandInStruct expands an In struct into its field dependencies func expandInStruct(t reflect.Type) ([]paramInfo, error) { - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } @@ -268,7 +268,7 @@ func expandInStruct(t reflect.Type) ([]paramInfo, error) { // expandOutStruct expands an Out struct into its result fields func expandOutStruct(t reflect.Type) ([]resultInfo, error) { - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } diff --git a/provide.go b/provide.go index ca07b44..1c562bc 100644 --- a/provide.go +++ b/provide.go @@ -17,7 +17,7 @@ func isTypeHealthCapable(t reflect.Type) bool { if t.Implements(healthCheckerType) { return true } - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { return t.Elem().Implements(healthCheckerType) } // Check pointer-to-type as well (methods may be on *T) @@ -106,7 +106,7 @@ func As(ifaces ...any) ConstructorOption { return constructorOptionFunc(func(c *constructorConfig) { for _, iface := range ifaces { t := reflect.TypeOf(iface) - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } c.asTypes = append(c.asTypes, t) @@ -475,7 +475,7 @@ func createAutoResolveFactory(info *constructorInfo, impl *containerImpl) Factor // resolveInStruct creates and populates an In struct with resolved dependencies func resolveInStruct(param paramInfo, impl *containerImpl) (reflect.Value, error) { structType := param.typ - isPtr := structType.Kind() == reflect.Ptr + isPtr := structType.Kind() == reflect.Pointer if isPtr { structType = structType.Elem() } @@ -577,7 +577,7 @@ func createMultiResultFactory(baseFactory Factory, fieldName string, resultType // Extract the specific field from Out struct by name resultValue := reflect.ValueOf(result) - if resultValue.Kind() == reflect.Ptr { + if resultValue.Kind() == reflect.Pointer { resultValue = resultValue.Elem() } diff --git a/type_registry.go b/type_registry.go index 4d1996e..d15c7e7 100644 --- a/type_registry.go +++ b/type_registry.go @@ -109,7 +109,7 @@ func deriveServiceName(key typeKey) string { return key.name } t := key.typ - for t.Kind() == reflect.Ptr { + for t.Kind() == reflect.Pointer { t = t.Elem() } pkg := t.PkgPath()