Skip to content

Commit 708bf57

Browse files
Šimon Šestákclaude
andcommitted
chore: Add CI/CD workflows and code quality tools
Add GitHub Actions workflows for testing, linting, and PR review: - test.yml: Run tests on macOS and Linux - lint.yml: SwiftLint validation in strict mode - danger.yml: Automated PR review with Futured rules Configure code quality tools: - .swiftlint.yml: Futured standard SwiftLint configuration - Dangerfile: PR validation rules (description, tests, TODOs, API changes) - Gemfile: Danger dependencies Fix SwiftLint violations throughout codebase: - Add appropriate disable comments for test files - Fix conditional return formatting in production code - Reorder function parameters to follow conventions - Add file-level disables for rules incompatible with library design Update .gitignore to exclude .claude directory All 65 tests passing with zero SwiftLint violations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent aadb939 commit 708bf57

20 files changed

+365
-42
lines changed

.github/actionlint-matcher.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"problemMatcher": [
3+
{
4+
"owner": "actionlint",
5+
"pattern": [
6+
{
7+
"regexp": "^(?:\u001b\\[\\d+m)?(.+?)(?:\u001b\\[\\d+m)?:(?:\u001b\\[\\d+m)?(\\d+)(?:\u001b\\[\\d+m)?:(?:\u001b\\[\\d+m)?(\\d+)(?:\u001b\\[\\d+m)?:\\s+(.+?)\\s+\\[(.+?)\\]$",
8+
"file": 1,
9+
"line": 2,
10+
"column": 3,
11+
"message": 4,
12+
"code": 5
13+
}
14+
]
15+
}
16+
]
17+
}

.github/workflows/danger.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Danger
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- '*'
7+
8+
jobs:
9+
danger:
10+
name: Danger PR Review
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Ruby
17+
uses: ruby/setup-ruby@v1
18+
with:
19+
ruby-version: '3.2'
20+
bundler-cache: true
21+
22+
- name: Run Danger
23+
env:
24+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
run: bundle exec danger

.github/workflows/lint.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Lint
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- '*'
7+
8+
jobs:
9+
swiftlint:
10+
name: SwiftLint
11+
runs-on: macos-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Install SwiftLint
17+
run: brew install swiftlint
18+
19+
- name: Run SwiftLint
20+
run: swiftlint lint --strict
21+
22+
actionlint:
23+
name: Workflow Lint
24+
runs-on: ubuntu-latest
25+
timeout-minutes: 30
26+
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Download actionlint
31+
id: get_actionlint
32+
run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
33+
shell: bash
34+
35+
- name: Register problem matcher
36+
run: echo "::add-matcher::.github/actionlint-matcher.json"
37+
38+
- name: Run actionlint
39+
run: ${{ steps.get_actionlint.outputs.executable }} -color
40+
shell: bash

.github/workflows/test.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- '*'
10+
11+
jobs:
12+
macos:
13+
name: macOS
14+
runs-on: macos-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Swift version
20+
run: swift --version
21+
22+
- name: Build
23+
run: swift build -v
24+
25+
- name: Run tests
26+
run: swift test -v
27+
28+
linux:
29+
name: Linux
30+
runs-on: ubuntu-latest
31+
32+
steps:
33+
- uses: actions/checkout@v4
34+
35+
- name: Swift version
36+
run: swift --version
37+
38+
- name: Build
39+
run: swift build -v
40+
41+
- name: Run tests
42+
run: swift test -v

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ DerivedData/
66
.swiftpm/configuration/registries.json
77
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
88
.netrc
9+
.claude

.swiftlint.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
disabled_rules:
2+
- line_length
3+
- blanket_disable_command
4+
- discouraged_optional_collection
5+
6+
excluded:
7+
- Pods
8+
- vendor
9+
- .build
10+
11+
opt_in_rules:
12+
- array_init
13+
- attributes
14+
- closure_body_length
15+
- closure_end_indentation
16+
- closure_spacing
17+
- collection_alignment
18+
- conditional_returns_on_newline
19+
- contains_over_filter_count
20+
- contains_over_filter_is_empty
21+
- contains_over_first_not_nil
22+
- contains_over_range_nil_comparison
23+
- convenience_type
24+
- discouraged_object_literal
25+
- discouraged_optional_boolean
26+
- empty_collection_literal
27+
- empty_count
28+
- empty_string
29+
- empty_xctest_method
30+
- enum_case_associated_values_count
31+
- explicit_init
32+
- fallthrough
33+
- fatal_error_message
34+
- file_name
35+
- file_name_no_space
36+
- first_where
37+
- flatmap_over_map_reduce
38+
- force_unwrapping
39+
- function_default_parameter_at_end
40+
- identical_operands
41+
- implicit_return
42+
- implicitly_unwrapped_optional
43+
- joined_default_parameter
44+
- last_where
45+
- legacy_multiple
46+
- legacy_random
47+
- let_var_whitespace
48+
- literal_expression_end_indentation
49+
- lower_acl_than_parent
50+
- modifier_order
51+
- multiline_arguments
52+
- multiline_function_chains
53+
- multiline_literal_brackets
54+
- multiline_parameters
55+
- multiline_parameters_brackets
56+
- nimble_operator
57+
- no_extension_access_modifier
58+
- number_separator
59+
- object_literal
60+
- operator_usage_whitespace
61+
- optional_enum_case_matching
62+
- overridden_super_call
63+
- override_in_extension
64+
- pattern_matching_keywords
65+
- prefer_self_type_over_type_of_self
66+
- private_action
67+
- private_outlet
68+
- prohibited_super_call
69+
- reduce_into
70+
- redundant_nil_coalescing
71+
- required_enum_case
72+
- single_test_class
73+
- sorted_first_last
74+
- sorted_imports
75+
- static_operator
76+
- strict_fileprivate
77+
- switch_case_on_newline
78+
- toggle_bool
79+
- trailing_closure
80+
- unneeded_parentheses_in_closure_argument
81+
- untyped_error_in_catch
82+
- vertical_parameter_alignment_on_call
83+
- vertical_whitespace_closing_braces
84+
- yoda_condition
85+
86+
analyzer_rules:
87+
- unused_declaration
88+
- unused_import
89+
90+
# Rule configurations
91+
identifier_name:
92+
excluded:
93+
- id
94+
- x
95+
- y
96+
- z
97+
98+
# Disable errors, allow only warnings
99+
cyclomatic_complexity:
100+
warning: 10
101+
type_name:
102+
max_length: 50
103+
force_cast: warning
104+
force_try: warning
105+
function_parameter_count: 5
106+
large_tuple:
107+
warning: 3
108+
error: 4

Dangerfile

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Dangerfile for FTNetworkTracer
2+
3+
# Import Futured Danger rules
4+
danger.import_dangerfile(gem: 'thefuntasty_danger')
5+
6+
# Custom rules for this project
7+
8+
# Ensure PR has a description
9+
if github.pr_body.length < 10
10+
warn("Please provide a meaningful PR description explaining what this PR does and why.")
11+
end
12+
13+
# Check for test changes
14+
has_app_changes = !git.modified_files.grep(/Sources/).empty?
15+
has_test_changes = !git.modified_files.grep(/Tests/).empty?
16+
17+
if has_app_changes && !has_test_changes && !github.pr_title.downcase.include?("docs")
18+
warn("Consider adding tests for your changes")
19+
end
20+
21+
# Check for large PRs
22+
if git.lines_of_code > 500
23+
warn("This PR is quite large. Consider breaking it into smaller PRs for easier review.")
24+
end
25+
26+
# Check for TODO/FIXME comments in modified files
27+
has_todos = git.modified_files.any? do |file|
28+
next unless file.end_with?('.swift')
29+
diff = git.diff_for_file(file)
30+
next unless diff
31+
diff.patch.include?('TODO:') || diff.patch.include?('FIXME:')
32+
end
33+
34+
if has_todos
35+
warn("This PR adds TODO or FIXME comments. Consider creating issues for them.")
36+
end
37+
38+
# Ensure README is updated if public API changes
39+
public_api_files = [
40+
'Sources/FTNetworkTracer/FTNetworkTracer.swift',
41+
'Sources/FTNetworkTracer/Analytics/AnalyticsProtocol.swift',
42+
'Sources/FTNetworkTracer/Logging/LoggerConfiguration.swift',
43+
'Sources/FTNetworkTracer/Analytics/AnalyticsConfiguration.swift'
44+
]
45+
46+
has_public_api_changes = !(git.modified_files & public_api_files).empty?
47+
has_readme_changes = git.modified_files.include?("README.md")
48+
49+
if has_public_api_changes && !has_readme_changes && !github.pr_title.include?("WIP")
50+
warn("Public API has changed. Consider updating README.md with usage examples.")
51+
end
52+
53+
# Check for security-sensitive changes
54+
security_files = git.modified_files.grep(/Analytics|Privacy|Mask|Security/)
55+
if !security_files.empty?
56+
message("⚠️ This PR modifies security-sensitive files: #{security_files.join(', ')}")
57+
message("Please ensure SecurityTests.swift covers these changes")
58+
end
59+
60+
# Celebrate achievements
61+
if git.lines_of_code > 100 && has_test_changes
62+
message("🎉 Great job adding comprehensive tests!")
63+
end
64+
65+
if git.modified_files.grep(/SecurityTests/).any?
66+
message("🔒 Security tests updated - excellent!")
67+
end

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'danger'
4+
gem 'thefuntasty_danger'

Package.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ let package = Package(
1515
.library(
1616
name: "FTNetworkTracer",
1717
targets: ["FTNetworkTracer"]
18-
),
18+
)
1919
],
2020
targets: [
2121
.target(
@@ -25,7 +25,6 @@ let package = Package(
2525
.testTarget(
2626
name: "FTNetworkTracerTests",
2727
dependencies: ["FTNetworkTracer"]
28-
),
28+
)
2929
]
3030
)
31-

0 commit comments

Comments
 (0)