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
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: CI

on:
push:
branches:
- main
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
name: Lint
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- name: Install SwiftLint
run: brew install swiftlint
- name: Run SwiftLint
run: swiftlint --strict

format:
name: Format
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- name: Install SwiftFormat
run: brew install swiftformat
# Paths come first: --lint would otherwise swallow the one after it.
- name: Check formatting
run: swiftformat Sources Preview --lint

build:
name: Build and Analyse
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- name: Install SwiftLint
run: brew install swiftlint
- name: Build and Analyse
run: |
set -o pipefail
for scheme in NecoSaver NecoSaverPreview; do
xcodebuild build analyze \
-project NecoSaver.xcodeproj \
-scheme "$scheme" \
-destination 'generic/platform=macOS' \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGNING_ALLOWED=NO \
| tee -a build.log
done
- name: SwiftLint Analyse
run: swiftlint analyze --strict --compiler-log-path build.log
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
## User settings
xcuserdata/

## Build output
build/
DerivedData/
dist/

## Obj-C/Swift specific
*.hmap

Expand Down
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.0
2 changes: 2 additions & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--swiftversion 6.0
--exclude Sources/Sprites.swift
21 changes: 21 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
excluded:
- Sources/Sprites.swift # generated
- build # xcodebuild output

disabled_rules:
- line_length
- nesting

# Require trailing commas to match SwiftFormat's trailingCommas rule.
trailing_comma:
mandatory_comma: true

# Pixel/geometry code uses short names like x, y, dx, dy.
identifier_name:
min_length:
warning: 1
error: 1

analyzer_rules:
- unused_declaration
- unused_import
80 changes: 80 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
PROJECT := NecoSaver.xcodeproj
SCHEME := NecoSaver
PREVIEW_SCHEME := NecoSaverPreview
CONFIGURATION := Release
DERIVED_DATA := build
PRODUCTS := $(DERIVED_DATA)/Build/Products/$(CONFIGURATION)
SAVER := $(PRODUCTS)/NecoSaver.saver
PREVIEW := $(PRODUCTS)/NecoSaverPreview.app/Contents/MacOS/NecoSaverPreview
INSTALL_DIR := $(HOME)/Library/Screen Savers
DIST_DIR := dist
DIST := $(DIST_DIR)/NecoSaver.zip
CHECKSUM := $(DIST_DIR)/checksum.txt
SUBMISSION := $(DERIVED_DATA)/submission.zip

# codesign resolves this by prefix, and there is only one such identity.
CODESIGN_IDENTITY ?= Developer ID Application
NOTARY_PROFILE ?= necosaver

XCODEBUILD := xcodebuild -project $(PROJECT) -configuration $(CONFIGURATION) -derivedDataPath $(DERIVED_DATA)

.DEFAULT_GOAL := build

.PHONY: build
build:
$(XCODEBUILD) -scheme $(SCHEME) build

.PHONY: install
install: build
mkdir -p "$(INSTALL_DIR)"
rm -rf "$(INSTALL_DIR)/NecoSaver.saver"
cp -R $(SAVER) "$(INSTALL_DIR)/"
@echo
@echo 'Installed. macOS caches the loaded bundle, so if an older build is'
@echo 'still running: killall legacyScreenSaver, then reopen System Settings.'

.PHONY: uninstall
uninstall:
rm -rf "$(INSTALL_DIR)/NecoSaver.saver"

.PHONY: preview
preview:
$(XCODEBUILD) -scheme $(PREVIEW_SCHEME) build
$(PREVIEW)

.PHONY: lint
lint:
swiftlint --strict

.PHONY: format
format:
swiftformat Sources Preview

# Signs with Developer ID rather than the ad-hoc signature a plain build
# produces, then notarizes. Gatekeeper rejects anything less once the bundle
# reaches another Mac and picks up a quarantine flag. Stapling attaches the
# ticket to the bundle so it validates without a network round trip.
.PHONY: release
release:
$(XCODEBUILD) -scheme $(SCHEME) \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="$(CODESIGN_IDENTITY)" \
OTHER_CODE_SIGN_FLAGS="--timestamp" \
build
codesign --verify --strict --verbose=2 $(SAVER)
rm -f $(SUBMISSION)
ditto -c -k --keepParent $(SAVER) $(SUBMISSION)
xcrun notarytool submit $(SUBMISSION) --keychain-profile "$(NOTARY_PROFILE)" --wait
xcrun stapler staple $(SAVER)
xcrun stapler validate $(SAVER)
mkdir -p $(DIST_DIR)
rm -f $(DIST) $(CHECKSUM)
ditto -c -k --keepParent $(SAVER) $(DIST)
cd $(DIST_DIR) && shasum -a 256 $(notdir $(DIST)) > $(notdir $(CHECKSUM))
@echo
@echo "Ready to distribute:"
@cat $(CHECKSUM)

.PHONY: clean
clean:
rm -rf $(DERIVED_DATA) dist
Loading
Loading