mirror of
https://github.com/kjanat/articulate-parser.git
synced 2026-01-16 11:42:09 +01:00
chore(ci): add linting and refine workflow dependencies
Adds a golangci-lint job to the CI pipeline to enforce code quality and style. The test job is now dependent on the new linting job. The final image build job is also updated to depend on the successful completion of the test, docker-test, and dependency-review jobs, ensuring more checks pass before publishing. Additionally, Go 1.25 is added to the testing matrix.
This commit is contained in:
40
.github/workflows/autofix.yml
vendored
40
.github/workflows/autofix.yml
vendored
@ -10,16 +10,36 @@ jobs:
|
|||||||
autofix:
|
autofix:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- name: Checkout code
|
||||||
- uses: actions/setup-go@v6
|
uses: actions/checkout@v5
|
||||||
with:
|
|
||||||
go-version-file: 'go.mod'
|
|
||||||
|
|
||||||
# goimports works like gofmt, but also fixes imports.
|
- name: Install Task
|
||||||
# see https://pkg.go.dev/golang.org/x/tools/cmd/goimports
|
uses: go-task/setup-task@v1
|
||||||
- run: go install golang.org/x/tools/cmd/goimports@latest
|
|
||||||
- run: goimports -w .
|
- uses: actions/setup-go@v6
|
||||||
# of course we can also do just this instead:
|
with: { go-version-file: 'go.mod' }
|
||||||
# - run: gofmt -w .
|
|
||||||
|
- name: Setup go deps
|
||||||
|
run: |
|
||||||
|
# Install golangci-lint
|
||||||
|
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin
|
||||||
|
|
||||||
|
# Install go-task dependencies
|
||||||
|
go install golang.org/x/tools/cmd/goimports@latest
|
||||||
|
|
||||||
|
- name: Run goimports
|
||||||
|
run: goimports -w .
|
||||||
|
|
||||||
|
- name: Run golangci-lint autofix
|
||||||
|
run: golangci-lint run --fix
|
||||||
|
|
||||||
|
- name: Run golangci-lint format
|
||||||
|
run: golangci-lint format
|
||||||
|
|
||||||
|
- name: Run go mod tidy
|
||||||
|
run: go mod tidy
|
||||||
|
|
||||||
|
- name: Run gopls modernize
|
||||||
|
run: task modernize
|
||||||
|
|
||||||
- uses: autofix-ci/action@v1
|
- uses: autofix-ci/action@v1
|
||||||
|
|||||||
270
.github/workflows/ci.yml
vendored
270
.github/workflows/ci.yml
vendored
@ -4,7 +4,6 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: ['master', 'develop']
|
branches: ['master', 'develop']
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ['master', 'develop', 'feature/*']
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: ghcr.io
|
REGISTRY: ghcr.io
|
||||||
@ -15,8 +14,24 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
golangci:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- uses: actions/setup-go@v6
|
||||||
|
with:
|
||||||
|
go-version: stable
|
||||||
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v8
|
||||||
|
with: { version: latest }
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test
|
name: Test
|
||||||
|
needs: [golangci]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@ -27,6 +42,7 @@ jobs:
|
|||||||
- 1.22.x
|
- 1.22.x
|
||||||
- 1.23.x
|
- 1.23.x
|
||||||
- 1.24.x
|
- 1.24.x
|
||||||
|
- 1.25.x
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
@ -52,11 +68,13 @@ jobs:
|
|||||||
- name: Run tests with enhanced reporting
|
- name: Run tests with enhanced reporting
|
||||||
id: test
|
id: test
|
||||||
run: |
|
run: |
|
||||||
echo "## 🔧 Test Environment" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
echo "- **Go Version:** ${{ matrix.go }}" >> $GITHUB_STEP_SUMMARY
|
## 🔧 Test Environment
|
||||||
echo "- **OS:** ubuntu-latest" >> $GITHUB_STEP_SUMMARY
|
- **Go Version:** ${{ matrix.go }}
|
||||||
echo "- **Timestamp:** $(date -u)" >> $GITHUB_STEP_SUMMARY
|
- **OS:** ubuntu-latest
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
- **Timestamp:** $(date -u)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
echo "Running tests with coverage..."
|
echo "Running tests with coverage..."
|
||||||
task test:coverage 2>&1 | tee test-output.log
|
task test:coverage 2>&1 | tee test-output.log
|
||||||
@ -69,30 +87,30 @@ jobs:
|
|||||||
SKIPPED_TESTS=$(grep -c "--- SKIP:" test-output.log || echo "0")
|
SKIPPED_TESTS=$(grep -c "--- SKIP:" test-output.log || echo "0")
|
||||||
|
|
||||||
# Generate test summary
|
# Generate test summary
|
||||||
echo "## 🧪 Test Results (Go ${{ matrix.go }})" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
## 🧪 Test Results (Go ${{ matrix.go }})
|
||||||
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "| Total Tests | $TOTAL_TESTS |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "| Passed | ✅ $PASSED_TESTS |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "| Failed | ❌ $FAILED_TESTS |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "| Skipped | ⏭️ $SKIPPED_TESTS |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "| Status | $([ $TEST_STATUS -eq 0 ] && echo "✅ PASSED" || echo "❌ FAILED") |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|
||||||
# Add package breakdown
|
| Metric | Value |
|
||||||
echo "### 📦 Package Test Results" >> $GITHUB_STEP_SUMMARY
|
| ----------- | ----------------------------------------------------------- |
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
| Total Tests | $TOTAL_TESTS |
|
||||||
echo "| Package | Status |" >> $GITHUB_STEP_SUMMARY
|
| Passed | $PASSED_TESTS |
|
||||||
echo "|---------|--------|" >> $GITHUB_STEP_SUMMARY
|
| Failed | $FAILED_TESTS |
|
||||||
|
| Skipped | $SKIPPED_TESTS |
|
||||||
|
| Status | $([ $TEST_STATUS -eq 0 ] && echo "PASSED" || echo "FAILED") |
|
||||||
|
|
||||||
|
### 📦 Package Test Results
|
||||||
|
|
||||||
|
| Package | Status |
|
||||||
|
|---------|--------|
|
||||||
|
EOF
|
||||||
|
|
||||||
# Extract package results
|
# Extract package results
|
||||||
grep "^ok\|^FAIL" test-output.log | while read line; do
|
grep "^ok\|^FAIL" test-output.log | while read -r line; do
|
||||||
if [[ $line == ok* ]]; then
|
if [[ $line == ok* ]]; then
|
||||||
pkg=$(echo $line | awk '{print $2}')
|
pkg=$(echo "$line" | awk '{print $2}')
|
||||||
echo "| $pkg | ✅ PASS |" >> $GITHUB_STEP_SUMMARY
|
echo "| $pkg | ✅ PASS |" >> $GITHUB_STEP_SUMMARY
|
||||||
elif [[ $line == FAIL* ]]; then
|
elif [[ $line == FAIL* ]]; then
|
||||||
pkg=$(echo $line | awk '{print $2}')
|
pkg=$(echo "$line" | awk '{print $2}')
|
||||||
echo "| $pkg | ❌ FAIL |" >> $GITHUB_STEP_SUMMARY
|
echo "| $pkg | ❌ FAIL |" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -101,19 +119,24 @@ jobs:
|
|||||||
|
|
||||||
# Add detailed results if tests failed
|
# Add detailed results if tests failed
|
||||||
if [ $TEST_STATUS -ne 0 ]; then
|
if [ $TEST_STATUS -ne 0 ]; then
|
||||||
echo "### ❌ Failed Tests Details" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
### ❌ Failed Tests Details
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
```
|
||||||
|
EOF
|
||||||
grep -A 10 "--- FAIL:" test-output.log | head -100 >> $GITHUB_STEP_SUMMARY
|
grep -A 10 "--- FAIL:" test-output.log | head -100 >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
```
|
||||||
|
|
||||||
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set outputs for other steps
|
# Set outputs for other steps
|
||||||
echo "test-status=$TEST_STATUS" >> $GITHUB_OUTPUT
|
cat >> $GITHUB_OUTPUT << EOF
|
||||||
echo "total-tests=$TOTAL_TESTS" >> $GITHUB_OUTPUT
|
test-status=$TEST_STATUS
|
||||||
echo "passed-tests=$PASSED_TESTS" >> $GITHUB_OUTPUT
|
total-tests=$TOTAL_TESTS
|
||||||
echo "failed-tests=$FAILED_TESTS" >> $GITHUB_OUTPUT
|
passed-tests=$PASSED_TESTS
|
||||||
|
failed-tests=$FAILED_TESTS
|
||||||
|
EOF
|
||||||
|
|
||||||
# Exit with the original test status
|
# Exit with the original test status
|
||||||
exit $TEST_STATUS
|
exit $TEST_STATUS
|
||||||
@ -124,33 +147,31 @@ jobs:
|
|||||||
if [ -f coverage/coverage.out ]; then
|
if [ -f coverage/coverage.out ]; then
|
||||||
COVERAGE=$(go tool cover -func=coverage/coverage.out | grep total | awk '{print $3}')
|
COVERAGE=$(go tool cover -func=coverage/coverage.out | grep total | awk '{print $3}')
|
||||||
|
|
||||||
echo "## 📊 Code Coverage (Go ${{ matrix.go }})" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
## 📊 Code Coverage (Go ${{ matrix.go }})
|
||||||
echo "**Total Coverage: $COVERAGE**" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|
||||||
# Add coverage by package
|
**Total Coverage: $COVERAGE**
|
||||||
echo "<details>" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "<summary>Click to expand 📋 Coverage by Package details</summary>" >> $GITHUB_STEP_SUMMARY
|
<details>
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
<summary>Click to expand 📋 Coverage by Package details</summary>
|
||||||
echo "| Package | Coverage |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "|---------|----------|" >> $GITHUB_STEP_SUMMARY
|
| Package | Coverage |
|
||||||
|
| ------- | -------- |
|
||||||
|
EOF
|
||||||
|
|
||||||
# Create temporary file for package coverage aggregation
|
# Create temporary file for package coverage aggregation
|
||||||
temp_coverage=$(mktemp)
|
temp_coverage=$(mktemp)
|
||||||
|
|
||||||
# Extract package-level coverage data
|
# Extract package-level coverage data
|
||||||
go tool cover -func=coverage/coverage.out | grep -v total | while read line; do
|
go tool cover -func=coverage/coverage.out | grep -v total | while read -r line; do
|
||||||
if [[ $line == *".go:"* ]]; then
|
if [[ $line == *".go:"* ]]; then
|
||||||
# Extract package path from file path (everything before the filename)
|
# Extract package path from file path (everything before the filename)
|
||||||
filepath=$(echo "$line" | awk '{print $1}')
|
filepath=$(echo "$line" | awk '{print $1}')
|
||||||
pkg_path=$(dirname "$filepath" | sed 's|github.com/kjanat/articulate-parser/||' | sed 's|^\./||')
|
pkg_path=$(dirname "$filepath" | sed 's|github.com/kjanat/articulate-parser/||; s|^\./||')
|
||||||
coverage=$(echo "$line" | awk '{print $3}' | sed 's/%//')
|
coverage=$(echo "$line" | awk '{print $3}' | sed 's/%//')
|
||||||
|
|
||||||
# Use root package if no subdirectory
|
# Use root package if no subdirectory
|
||||||
if [[ "$pkg_path" == "." || "$pkg_path" == "" ]]; then
|
[[ "$pkg_path" == "." || "$pkg_path" == "" ]] && pkg_path="root"
|
||||||
pkg_path="root"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$pkg_path $coverage" >> "$temp_coverage"
|
echo "$pkg_path $coverage" >> "$temp_coverage"
|
||||||
fi
|
fi
|
||||||
@ -158,7 +179,7 @@ jobs:
|
|||||||
|
|
||||||
# Aggregate coverage by package (average)
|
# Aggregate coverage by package (average)
|
||||||
awk '{
|
awk '{
|
||||||
packages[$1] += $2;
|
packages[$1] += $2
|
||||||
counts[$1]++
|
counts[$1]++
|
||||||
}
|
}
|
||||||
END {
|
END {
|
||||||
@ -166,17 +187,21 @@ jobs:
|
|||||||
avg = packages[pkg] / counts[pkg]
|
avg = packages[pkg] / counts[pkg]
|
||||||
printf "| %s | %.1f%% |\n", pkg, avg
|
printf "| %s | %.1f%% |\n", pkg, avg
|
||||||
}
|
}
|
||||||
}' $temp_coverage | sort >> $GITHUB_STEP_SUMMARY
|
}' "$temp_coverage" | sort >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
rm -f $temp_coverage
|
rm -f "$temp_coverage"
|
||||||
|
|
||||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
</details>
|
||||||
|
|
||||||
|
EOF
|
||||||
else
|
else
|
||||||
echo "## ⚠️ Coverage Report" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "No coverage file generated" >> $GITHUB_STEP_SUMMARY
|
## ⚠️ Coverage Report
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
No coverage file generated
|
||||||
|
|
||||||
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload test artifacts
|
- name: Upload test artifacts
|
||||||
@ -191,8 +216,11 @@ jobs:
|
|||||||
|
|
||||||
- name: Run linters
|
- name: Run linters
|
||||||
run: |
|
run: |
|
||||||
echo "## 🔍 Static Analysis (Go ${{ matrix.go }})" >> $GITHUB_STEP_SUMMARY
|
# Initialize summary
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << EOF
|
||||||
|
## 🔍 Static Analysis (Go ${{ matrix.go }})
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
# Run go vet
|
# Run go vet
|
||||||
VET_OUTPUT=$(task lint:vet 2>&1 || echo "")
|
VET_OUTPUT=$(task lint:vet 2>&1 || echo "")
|
||||||
@ -201,11 +229,13 @@ jobs:
|
|||||||
if [ $VET_STATUS -eq 0 ]; then
|
if [ $VET_STATUS -eq 0 ]; then
|
||||||
echo "✅ **go vet:** No issues found" >> $GITHUB_STEP_SUMMARY
|
echo "✅ **go vet:** No issues found" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "❌ **go vet:** Issues found" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
❌ **go vet:** Issues found
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
```
|
||||||
|
EOF
|
||||||
echo "$VET_OUTPUT" >> $GITHUB_STEP_SUMMARY
|
echo "$VET_OUTPUT" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
@ -216,32 +246,33 @@ jobs:
|
|||||||
if [ $FMT_STATUS -eq 0 ]; then
|
if [ $FMT_STATUS -eq 0 ]; then
|
||||||
echo "✅ **go fmt:** All files properly formatted" >> $GITHUB_STEP_SUMMARY
|
echo "✅ **go fmt:** All files properly formatted" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "❌ **go fmt:** Files need formatting" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
❌ **go fmt:** Files need formatting
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
```
|
||||||
|
EOF
|
||||||
echo "$FMT_OUTPUT" >> $GITHUB_STEP_SUMMARY
|
echo "$FMT_OUTPUT" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exit with error if any linter failed
|
# Exit with error if any linter failed
|
||||||
if [ $VET_STATUS -ne 0 ] || [ $FMT_STATUS -ne 0 ]; then
|
[ $VET_STATUS -eq 0 ] && [ $FMT_STATUS -eq 0 ] || exit 1
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Job Summary
|
- name: Job Summary
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
echo "## 📋 Job Summary (Go ${{ matrix.go }})" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
## 📋 Job Summary (Go ${{ matrix.go }})
|
||||||
echo "| Step | Status |" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
|
| Step | Status |
|
||||||
echo "| Dependencies | ✅ Success |" >> $GITHUB_STEP_SUMMARY
|
| --------------- | --------------------------------------------------------------- |
|
||||||
echo "| Build | ✅ Success |" >> $GITHUB_STEP_SUMMARY
|
| Dependencies | Success |
|
||||||
echo "| Tests | ${{ steps.test.outcome == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
|
| Build | Success |
|
||||||
echo "| Coverage | ${{ job.status == 'success' && '✅ Generated' || '⚠️ Partial' }} |" >> $GITHUB_STEP_SUMMARY
|
| Tests | ${{ steps.test.outcome == 'success' && 'Success' || 'Failed' }} |
|
||||||
echo "| Static Analysis | ${{ job.status == 'success' && '✅ Clean' || '❌ Issues' }} |" >> $GITHUB_STEP_SUMMARY
|
| Coverage | ${{ job.status == 'success' && 'Generated' || 'Partial' }} |
|
||||||
echo "| Code Formatting | ${{ job.status == 'success' && '✅ Clean' || '❌ Issues' }} |" >> $GITHUB_STEP_SUMMARY
|
| Static Analysis | ${{ job.status == 'success' && 'Clean' || 'Issues' }} |
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
| Code Formatting | ${{ job.status == 'success' && 'Clean' || 'Issues' }} |
|
||||||
|
EOF
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
- name: Upload coverage reports to Codecov
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v5
|
||||||
@ -285,16 +316,18 @@ jobs:
|
|||||||
|
|
||||||
- name: Test Docker image using Task
|
- name: Test Docker image using Task
|
||||||
run: |
|
run: |
|
||||||
echo "## 🧪 Docker Image Tests" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
## 🧪 Docker Image Tests
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
# Run Task docker test
|
# Run Task docker test
|
||||||
task docker:test
|
task docker:test
|
||||||
|
|
||||||
echo "**Testing help command:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Testing help command:**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo '```terminaloutput' >> $GITHUB_STEP_SUMMARY
|
||||||
docker run --rm articulate-parser:latest --help >> $GITHUB_STEP_SUMMARY
|
docker run --rm articulate-parser:latest --help >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Test image size
|
# Test image size
|
||||||
@ -324,8 +357,11 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
packages: write
|
||||||
needs: ['test']
|
needs: [test, docker-test, dependency-review]
|
||||||
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/feature/docker'))
|
if: |
|
||||||
|
github.event_name == 'push' && (github.ref == 'refs/heads/master' ||
|
||||||
|
github.ref == 'refs/heads/develop' ||
|
||||||
|
startsWith(github.ref, 'refs/heads/feature/docker'))
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
@ -400,35 +436,39 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate Docker summary
|
- name: Generate Docker summary
|
||||||
run: |
|
run: |
|
||||||
echo "## 🐳 Docker Build Summary" >> $GITHUB_STEP_SUMMARY
|
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
## 🐳 Docker Build Summary
|
||||||
echo "**Image:** \`ghcr.io/${{ github.repository }}\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
**Image:** `ghcr.io/${{ github.repository }}`
|
||||||
echo "**Tags built:**" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
**Tags built:**
|
||||||
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
```text
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
${{ steps.meta.outputs.tags }}
|
||||||
echo "**Features:**" >> $GITHUB_STEP_SUMMARY
|
```
|
||||||
echo "- **Platforms:** linux/amd64, linux/arm64, linux/arm/v7, linux/386, linux/ppc64le, linux/s390x" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Architecture optimization:** ✅ Native compilation for each platform" >> $GITHUB_STEP_SUMMARY
|
**Features:**
|
||||||
echo "- **Multi-arch image description:** ✅ Enabled" >> $GITHUB_STEP_SUMMARY
|
- **Platforms:** linux/amd64, linux/arm64, linux/arm/v7, linux/386, linux/ppc64le, linux/s390x
|
||||||
echo "- **SBOM (Software Bill of Materials):** ✅ Generated" >> $GITHUB_STEP_SUMMARY
|
- **Architecture optimization:** Native compilation for each platform
|
||||||
echo "- **Provenance attestation:** ✅ Generated" >> $GITHUB_STEP_SUMMARY
|
- **Multi-arch image description:** Enabled
|
||||||
echo "- **Security scanning:** Ready for vulnerability analysis" >> $GITHUB_STEP_SUMMARY
|
- **SBOM (Software Bill of Materials):** Generated
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
- **Provenance attestation:** Generated
|
||||||
echo "**Usage:**" >> $GITHUB_STEP_SUMMARY
|
- **Security scanning:** Ready for vulnerability analysis
|
||||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "# Pull the image" >> $GITHUB_STEP_SUMMARY
|
**Usage:**
|
||||||
echo "docker pull ghcr.io/${{ github.repository }}:latest" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
```bash
|
||||||
echo "# Run with help" >> $GITHUB_STEP_SUMMARY
|
# Pull the image
|
||||||
echo "docker run --rm ghcr.io/${{ github.repository }}:latest --help" >> $GITHUB_STEP_SUMMARY
|
docker pull ghcr.io/${{ github.repository }}:latest
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "# Process a local file (mount current directory)" >> $GITHUB_STEP_SUMMARY
|
# Run with help
|
||||||
echo "docker run --rm -v \$(pwd):/workspace ghcr.io/${{ github.repository }}:latest /workspace/input.json markdown /workspace/output.md" >> $GITHUB_STEP_SUMMARY
|
docker run --rm ghcr.io/${{ github.repository }}:latest --help
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
# Process a local file (mount current directory)
|
||||||
|
docker run --rm -v $(pwd):/workspace ghcr.io/${{ github.repository }}:latest /workspace/input.json markdown /workspace/output.md
|
||||||
|
```
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
# Security and quality analysis workflows
|
# Security and quality analysis workflows
|
||||||
codeql-analysis:
|
codeql-analysis:
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -75,3 +75,5 @@ main_coverage
|
|||||||
**/*.local.*
|
**/*.local.*
|
||||||
|
|
||||||
.claude/
|
.claude/
|
||||||
|
|
||||||
|
NUL
|
||||||
|
|||||||
381
.golangci.yml
Normal file
381
.golangci.yml
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
# golangci-lint configuration for articulate-parser
|
||||||
|
# https://golangci-lint.run/usage/configuration/
|
||||||
|
|
||||||
|
version: "2"
|
||||||
|
|
||||||
|
# Options for analysis running
|
||||||
|
run:
|
||||||
|
# Timeout for total work
|
||||||
|
timeout: 5m
|
||||||
|
|
||||||
|
# Skip directories (not allowed in config v2, will use issues exclude instead)
|
||||||
|
|
||||||
|
# Go version
|
||||||
|
go: "1.24"
|
||||||
|
|
||||||
|
# Include test files
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
# Use Go module mode
|
||||||
|
modules-download-mode: readonly
|
||||||
|
|
||||||
|
# Output configuration
|
||||||
|
output:
|
||||||
|
# Format of output
|
||||||
|
formats:
|
||||||
|
text:
|
||||||
|
print-issued-lines: true
|
||||||
|
print-linter-name: true
|
||||||
|
|
||||||
|
# Sort results
|
||||||
|
sort-order:
|
||||||
|
- linter
|
||||||
|
- severity
|
||||||
|
- file
|
||||||
|
|
||||||
|
# Show statistics
|
||||||
|
show-stats: true
|
||||||
|
|
||||||
|
# Issues configuration
|
||||||
|
issues:
|
||||||
|
# Maximum issues count per one linter
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
|
||||||
|
# Maximum count of issues with the same text
|
||||||
|
max-same-issues: 3
|
||||||
|
|
||||||
|
# Show only new issues
|
||||||
|
new: false
|
||||||
|
|
||||||
|
# Fix found issues (if linter supports)
|
||||||
|
fix: false
|
||||||
|
|
||||||
|
# Formatters configuration
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gofumpt
|
||||||
|
settings:
|
||||||
|
# gofmt settings
|
||||||
|
gofmt:
|
||||||
|
simplify: true
|
||||||
|
|
||||||
|
# goimports settings
|
||||||
|
goimports:
|
||||||
|
local-prefixes:
|
||||||
|
- github.com/kjanat/articulate-parser
|
||||||
|
|
||||||
|
# gofumpt settings
|
||||||
|
gofumpt:
|
||||||
|
module-path: github.com/kjanat/articulate-parser
|
||||||
|
extra-rules: true
|
||||||
|
|
||||||
|
# Linters configuration
|
||||||
|
linters:
|
||||||
|
# Default set of linters
|
||||||
|
default: none
|
||||||
|
|
||||||
|
# Enable specific linters
|
||||||
|
enable:
|
||||||
|
# Default/standard linters
|
||||||
|
- errcheck # Check for unchecked errors
|
||||||
|
- govet # Go vet
|
||||||
|
- ineffassign # Detect ineffectual assignments
|
||||||
|
- staticcheck # Staticcheck
|
||||||
|
- unused # Find unused code
|
||||||
|
|
||||||
|
# Code quality
|
||||||
|
- revive # Fast, configurable linter
|
||||||
|
- gocritic # Opinionated Go source code linter
|
||||||
|
- godot # Check comment periods
|
||||||
|
- godox # Detect TODO/FIXME comments
|
||||||
|
- gocognit # Cognitive complexity
|
||||||
|
- gocyclo # Cyclomatic complexity
|
||||||
|
- funlen # Function length
|
||||||
|
- maintidx # Maintainability index
|
||||||
|
|
||||||
|
# Security
|
||||||
|
- gosec # Security problems
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
- prealloc # Find slice preallocation opportunities
|
||||||
|
- bodyclose # Check HTTP response body closed
|
||||||
|
|
||||||
|
# Style and formatting
|
||||||
|
- goconst # Find repeated strings
|
||||||
|
- misspell # Find misspellings
|
||||||
|
- whitespace # Find unnecessary blank lines
|
||||||
|
- unconvert # Remove unnecessary type conversions
|
||||||
|
- dupword # Check for duplicate words
|
||||||
|
|
||||||
|
# Error handling
|
||||||
|
- errorlint # Error handling improvements
|
||||||
|
- wrapcheck # Check error wrapping
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
- testifylint # Testify usage
|
||||||
|
- tparallel # Detect improper t.Parallel() usage
|
||||||
|
- thelper # Detect test helpers without t.Helper()
|
||||||
|
|
||||||
|
# Best practices
|
||||||
|
- exhaustive # Check exhaustiveness of enum switches
|
||||||
|
- nolintlint # Check nolint directives
|
||||||
|
- nakedret # Find naked returns
|
||||||
|
- nilnil # Check for redundant nil checks
|
||||||
|
- noctx # Check sending HTTP requests without context
|
||||||
|
- contextcheck # Check context propagation
|
||||||
|
- asciicheck # Check for non-ASCII identifiers
|
||||||
|
- bidichk # Check for dangerous unicode sequences
|
||||||
|
- durationcheck # Check for multiplied durations
|
||||||
|
- makezero # Find slice declarations with non-zero length
|
||||||
|
- nilerr # Find code returning nil with non-nil error
|
||||||
|
- predeclared # Find code shadowing predeclared identifiers
|
||||||
|
- promlinter # Check Prometheus metrics naming
|
||||||
|
- reassign # Check reassignment of package variables
|
||||||
|
- usestdlibvars # Use variables from stdlib
|
||||||
|
- wastedassign # Find wasted assignments
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
- godoclint # Check godoc comments
|
||||||
|
|
||||||
|
# New
|
||||||
|
- modernize # Suggest simplifications using new Go features
|
||||||
|
|
||||||
|
# Exclusion rules for linters
|
||||||
|
exclusions:
|
||||||
|
rules:
|
||||||
|
# Exclude some linters from test files
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- goconst
|
||||||
|
- funlen
|
||||||
|
- goerr113
|
||||||
|
|
||||||
|
# Exclude benchmarks from some linters
|
||||||
|
- path: _bench_test\.go
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
- dupl
|
||||||
|
- errcheck
|
||||||
|
- goconst
|
||||||
|
- funlen
|
||||||
|
- goerr113
|
||||||
|
- wrapcheck
|
||||||
|
|
||||||
|
# Exclude example tests
|
||||||
|
- path: _example_test\.go
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
- errcheck
|
||||||
|
- funlen
|
||||||
|
- goerr113
|
||||||
|
- wrapcheck
|
||||||
|
- revive
|
||||||
|
|
||||||
|
# Exclude linters for main.go
|
||||||
|
- path: ^main\.go$
|
||||||
|
linters:
|
||||||
|
- forbidigo
|
||||||
|
|
||||||
|
# Exclude certain linters for generated files
|
||||||
|
- path: internal/version/version.go
|
||||||
|
linters:
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
|
||||||
|
# Allow fmt.Print* in main package
|
||||||
|
- path: ^main\.go$
|
||||||
|
text: "use of fmt.Print"
|
||||||
|
linters:
|
||||||
|
- forbidigo
|
||||||
|
|
||||||
|
# Exclude common false positives
|
||||||
|
- text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked"
|
||||||
|
linters:
|
||||||
|
- errcheck
|
||||||
|
|
||||||
|
# Exclude error wrapping suggestions for well-known errors
|
||||||
|
- text: "non-wrapping format verb for fmt.Errorf"
|
||||||
|
linters:
|
||||||
|
- errorlint
|
||||||
|
|
||||||
|
# Linters settings
|
||||||
|
settings:
|
||||||
|
# errcheck settings
|
||||||
|
errcheck:
|
||||||
|
check-type-assertions: true
|
||||||
|
check-blank: false
|
||||||
|
|
||||||
|
# govet settings
|
||||||
|
govet:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- fieldalignment # Too many false positives
|
||||||
|
- shadow # Can be noisy
|
||||||
|
|
||||||
|
# goconst settings
|
||||||
|
goconst:
|
||||||
|
min-len: 3
|
||||||
|
min-occurrences: 3
|
||||||
|
|
||||||
|
# godot settings
|
||||||
|
godot:
|
||||||
|
scope: toplevel
|
||||||
|
exclude:
|
||||||
|
- "^fixme:"
|
||||||
|
- "^todo:"
|
||||||
|
capital: true
|
||||||
|
period: true
|
||||||
|
|
||||||
|
# godox settings
|
||||||
|
godox:
|
||||||
|
keywords:
|
||||||
|
- TODO
|
||||||
|
- FIXME
|
||||||
|
- HACK
|
||||||
|
- BUG
|
||||||
|
- XXX
|
||||||
|
|
||||||
|
# misspell settings
|
||||||
|
misspell:
|
||||||
|
locale: US
|
||||||
|
|
||||||
|
# funlen settings
|
||||||
|
funlen:
|
||||||
|
lines: 100
|
||||||
|
statements: 50
|
||||||
|
|
||||||
|
# gocognit settings
|
||||||
|
gocognit:
|
||||||
|
min-complexity: 20
|
||||||
|
|
||||||
|
# gocyclo settings
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 15
|
||||||
|
|
||||||
|
# gocritic settings
|
||||||
|
gocritic:
|
||||||
|
enabled-tags:
|
||||||
|
- diagnostic
|
||||||
|
- style
|
||||||
|
- performance
|
||||||
|
- experimental
|
||||||
|
disabled-checks:
|
||||||
|
- ifElseChain
|
||||||
|
- singleCaseSwitch
|
||||||
|
- commentedOutCode
|
||||||
|
settings:
|
||||||
|
hugeParam:
|
||||||
|
sizeThreshold: 512
|
||||||
|
rangeValCopy:
|
||||||
|
sizeThreshold: 512
|
||||||
|
|
||||||
|
# gosec settings
|
||||||
|
gosec:
|
||||||
|
severity: medium
|
||||||
|
confidence: medium
|
||||||
|
excludes:
|
||||||
|
- G104 # Handled by errcheck
|
||||||
|
- G304 # File path provided as taint input
|
||||||
|
|
||||||
|
# revive settings
|
||||||
|
revive:
|
||||||
|
severity: warning
|
||||||
|
rules:
|
||||||
|
- name: blank-imports
|
||||||
|
- name: context-as-argument
|
||||||
|
- name: context-keys-type
|
||||||
|
- name: dot-imports
|
||||||
|
- name: empty-block
|
||||||
|
- name: error-naming
|
||||||
|
- name: error-return
|
||||||
|
- name: error-strings
|
||||||
|
- name: errorf
|
||||||
|
- name: exported
|
||||||
|
- name: if-return
|
||||||
|
- name: increment-decrement
|
||||||
|
- name: indent-error-flow
|
||||||
|
- name: package-comments
|
||||||
|
- name: range
|
||||||
|
- name: receiver-naming
|
||||||
|
- name: time-naming
|
||||||
|
- name: unexported-return
|
||||||
|
- name: var-declaration
|
||||||
|
- name: var-naming
|
||||||
|
|
||||||
|
# errorlint settings
|
||||||
|
errorlint:
|
||||||
|
errorf: true
|
||||||
|
errorf-multi: true
|
||||||
|
asserts: true
|
||||||
|
comparison: true
|
||||||
|
|
||||||
|
# wrapcheck settings
|
||||||
|
wrapcheck:
|
||||||
|
ignore-sigs:
|
||||||
|
- .Errorf(
|
||||||
|
- errors.New(
|
||||||
|
- errors.Unwrap(
|
||||||
|
- errors.Join(
|
||||||
|
- .WithMessage(
|
||||||
|
- .WithMessagef(
|
||||||
|
- .WithStack(
|
||||||
|
ignore-package-globs:
|
||||||
|
- github.com/kjanat/articulate-parser/*
|
||||||
|
|
||||||
|
# exhaustive settings
|
||||||
|
exhaustive:
|
||||||
|
check:
|
||||||
|
- switch
|
||||||
|
- map
|
||||||
|
default-signifies-exhaustive: true
|
||||||
|
|
||||||
|
# nolintlint settings
|
||||||
|
nolintlint:
|
||||||
|
allow-unused: false
|
||||||
|
require-explanation: true
|
||||||
|
require-specific: true
|
||||||
|
|
||||||
|
# stylecheck settings
|
||||||
|
staticcheck:
|
||||||
|
checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"]
|
||||||
|
|
||||||
|
# maintidx settings
|
||||||
|
maintidx:
|
||||||
|
under: 20
|
||||||
|
|
||||||
|
# testifylint settings
|
||||||
|
testifylint:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- float-compare
|
||||||
|
|
||||||
|
# thelper settings
|
||||||
|
thelper:
|
||||||
|
test:
|
||||||
|
first: true
|
||||||
|
name: true
|
||||||
|
begin: true
|
||||||
|
benchmark:
|
||||||
|
first: true
|
||||||
|
name: true
|
||||||
|
begin: true
|
||||||
|
|
||||||
|
# Severity rules
|
||||||
|
severity:
|
||||||
|
default: warning
|
||||||
|
rules:
|
||||||
|
- linters:
|
||||||
|
- gosec
|
||||||
|
severity: error
|
||||||
|
- linters:
|
||||||
|
- errcheck
|
||||||
|
- staticcheck
|
||||||
|
severity: error
|
||||||
|
- linters:
|
||||||
|
- godox
|
||||||
|
severity: info
|
||||||
Reference in New Issue
Block a user