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
14 changes: 14 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
coverage:
status:
project:
default:
target: 70%
threshold: 2%
patch:
default:
target: 60%

comment:
layout: "reach,diff,flags,files"
behavior: default
require_changes: true
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Global owner — auto-requested as reviewer on every PR
* @ANSCoder
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,24 @@ jobs:
- name: Build
run: swift build -c release

- name: Test
run: swift test
- name: Test with coverage
run: swift test --enable-code-coverage

- name: Generate coverage report
run: |
xcrun llvm-cov export \
.build/debug/NexioPackageTests.xctest/Contents/MacOS/NexioPackageTests \
-instr-profile .build/debug/codecov/default.profdata \
-ignore-filename-regex ".build|Tests" \
-format lcov > coverage.lcov

- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
files: coverage.lcov
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

# ── Swift 6 strict concurrency ────────────────────────────────────────────
swift6:
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/danger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Danger

on:
pull_request:
branches: [main]

jobs:
danger:
name: Danger Swift
runs-on: macos-15
if: github.event_name == 'pull_request'
permissions:
pull-requests: write
issues: write
statuses: write

steps:
- uses: actions/checkout@v4

- name: Select Xcode 16.3
run: sudo xcode-select -s /Applications/Xcode_16.3.app

- name: Install Danger Swift
run: brew install danger/tap/danger-swift

- name: Run Danger
run: danger-swift ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38 changes: 38 additions & 0 deletions Dangerfile.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2026 ANSCoder
// Licensed under the MIT License. See LICENSE in the project root for details.

import Danger

let danger = Danger()

// Warn on large PRs
let bigPRThreshold = 400
let additions = danger.github.pullRequest.additions ?? 0
let deletions = danger.github.pullRequest.deletions ?? 0
if additions + deletions > bigPRThreshold {
warn("PR is large (\(additions + deletions) lines). Consider splitting.")
}

// Require CHANGELOG update for non-trivial PRs
let hasChangelogUpdate = danger.git.modifiedFiles.contains("CHANGELOG.md")
|| danger.git.createdFiles.contains("CHANGELOG.md")
let isTrivial = danger.github.pullRequest.title.contains("[trivial]")
|| danger.github.pullRequest.title.contains("docs:")
|| danger.github.pullRequest.title.contains("chore:")
if !hasChangelogUpdate && !isTrivial {
warn("No `CHANGELOG.md` update. Add an entry under `[Unreleased]` or prefix title with `chore:`/`docs:` to skip.")
}

// Require PR description
let bodyLength = danger.github.pullRequest.body?.count ?? 0
if bodyLength < 20 {
fail("PR description is too short. Explain what changed and why.")
}

// Warn if tests were not touched when source was modified
let sourceChanged = danger.git.modifiedFiles.contains { $0.hasPrefix("Sources/") }
let testsChanged = danger.git.modifiedFiles.contains { $0.hasPrefix("Tests/") }
|| danger.git.createdFiles.contains { $0.hasPrefix("Tests/") }
if sourceChanged && !testsChanged {
warn("Source files changed but no test files modified. Add or update tests where appropriate.")
}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
[![Platforms](https://img.shields.io/badge/Platforms-iOS%2016%20·%20macOS%2013%20·%20watchOS%209%20·%20tvOS%2016-blue.svg)](https://developer.apple.com)
[![SPM](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://swift.org/package-manager)
[![License](https://img.shields.io/badge/License-MIT-lightgrey.svg)](LICENSE)
[![CI](https://github.com/ANSCoder/Nexio/actions/workflows/ci.yml/badge.svg)](https://github.com/ANSCoder/Nexio/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/ANSCoder/Nexio/branch/main/graph/badge.svg)](https://codecov.io/gh/ANSCoder/Nexio)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FANSCoder%2FNexio%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/ANSCoder/Nexio)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FANSCoder%2FNexio%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/ANSCoder/Nexio)

Typed JSON requests · Auth strategies · Retry with backoff · Interceptor pipeline · SwiftUI image loading · Zero dependencies

Expand Down
Loading