ci: add Gitea Actions CI/CD, branch workflow, and contributor docs

- .gitea/workflows/ci.yml: build + test KisaniCal scheme on a self-hosted
  macOS runner for every PR into main/develop (and pushes to develop).
- .gitea/workflows/release.yml: archive + export IPA on push to main, with
  a commented TestFlight upload placeholder (App Store Connect API key).
- ExportOptions.plist: export template (Team ID K8BLMMR883, app-store method).
- scripts/gitea-setup.sh: idempotent Gitea API setup for develop default
  branch + main branch protection.
- CONTRIBUTING.md: feature/* -> develop -> main workflow and PR gate rules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kutesir
2026-07-03 01:38:22 +03:00
committed by kutesir
parent c0dd298e5b
commit cf5dc8943a
5 changed files with 360 additions and 0 deletions

86
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,86 @@
name: CI
# Build + test on every PR into main or develop (and on direct pushes to develop).
on:
pull_request:
branches: [main, develop]
push:
branches: [develop]
# ⚠️ RUNNER LABELS — must match how your Mac runner was registered with act_runner.
# Check your runner's labels in Gitea: Settings → Actions → Runners (click the runner).
# If it registered as e.g. `macos` or `self-hosted`, change `runs-on` below to match.
# `[self-hosted, macOS]` means "a runner that has BOTH labels".
jobs:
build-and-test:
runs-on: [self-hosted, macOS]
env:
SCHEME: KisaniCal
PROJECT: KisaniCal.xcodeproj
steps:
- name: Checkout
uses: actions/checkout@v4
# The .xcodeproj is generated from project.yml via XcodeGen.
# Regenerate it so CI never builds a stale project. No-op if xcodegen isn't installed.
- name: Regenerate Xcode project (XcodeGen)
run: |
if command -v xcodegen >/dev/null 2>&1; then
xcodegen generate
else
echo "xcodegen not found on runner — using committed ${PROJECT}."
echo "Install with: brew install xcodegen"
fi
- name: Show toolchain
run: |
xcodebuild -version
xcrun simctl list runtimes | grep -i ios || true
# Pick a concrete, bootable iOS Simulator (needed for `xcodebuild test`).
- name: Select iOS Simulator destination
id: sim
run: |
# First available iPhone simulator on any installed iOS runtime.
UDID=$(xcrun simctl list devices available -j | python3 -c "import json,sys,re; d=json.load(sys.stdin)['devices']; devs=[x for k,v in d.items() if re.search('iOS',k) for x in v if x.get('isAvailable') and 'iPhone' in x['name']]; print(devs[0]['udid'] if devs else '')")
if [ -z "$UDID" ]; then
echo "No available iPhone simulator found on the runner." >&2
echo "Install an iOS runtime via Xcode → Settings → Components." >&2
exit 1
fi
echo "udid=$UDID" >> "$GITHUB_OUTPUT"
echo "Using simulator UDID: $UDID"
- name: Build
run: |
set -o pipefail
xcodebuild build \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Debug \
-destination "id=${{ steps.sim.outputs.udid }}" \
CODE_SIGNING_ALLOWED=NO \
| xcbeautify || xcodebuild build \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Debug \
-destination "id=${{ steps.sim.outputs.udid }}" \
CODE_SIGNING_ALLOWED=NO
- name: Test
run: |
set -o pipefail
xcodebuild test \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Debug \
-destination "id=${{ steps.sim.outputs.udid }}" \
CODE_SIGNING_ALLOWED=NO \
| xcbeautify || xcodebuild test \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Debug \
-destination "id=${{ steps.sim.outputs.udid }}" \
CODE_SIGNING_ALLOWED=NO

View File

@@ -0,0 +1,86 @@
name: Release
# Runs only when code lands on main (i.e. after a PR is merged).
on:
push:
branches: [main]
# ⚠️ Same runner-label caveat as ci.yml — adjust `runs-on` to match your registered runner.
jobs:
archive-and-export:
runs-on: [self-hosted, macOS]
env:
SCHEME: KisaniCal
PROJECT: KisaniCal.xcodeproj
# A real distribution build MUST be signed. This requires an Apple
# Distribution certificate + provisioning profile installed in the
# runner's login keychain (see notes at the bottom of this file).
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Regenerate Xcode project (XcodeGen)
run: |
if command -v xcodegen >/dev/null 2>&1; then xcodegen generate; fi
- name: Archive
run: |
set -o pipefail
xcodebuild archive \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath "$RUNNER_TEMP/KisaniCal.xcarchive" \
-allowProvisioningUpdates
- name: Export IPA
run: |
set -o pipefail
xcodebuild -exportArchive \
-archivePath "$RUNNER_TEMP/KisaniCal.xcarchive" \
-exportOptionsPlist ExportOptions.plist \
-exportPath "$RUNNER_TEMP/export" \
-allowProvisioningUpdates
ls -la "$RUNNER_TEMP/export"
# ------------------------------------------------------------------
# PLACEHOLDER: Upload to TestFlight / App Store Connect.
#
# Add these as Gitea repo secrets: Settings → Actions → Secrets
# APP_STORE_CONNECT_API_KEY_ID (the "Key ID" from App Store Connect)
# APP_STORE_CONNECT_ISSUER_ID (the "Issuer ID")
# APP_STORE_CONNECT_API_KEY_P8 (contents of the AuthKey_XXXX.p8 file)
#
# Then uncomment ONE of the approaches below.
# ------------------------------------------------------------------
# --- Option A: modern notarytool / App Store Connect API key (recommended) ---
# - name: Write API key to file
# run: |
# mkdir -p ~/private_keys
# echo "${{ secrets.APP_STORE_CONNECT_API_KEY_P8 }}" > ~/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}.p8
#
# - name: Upload to TestFlight (altool with API key)
# run: |
# xcrun altool --upload-app \
# --type ios \
# --file "$RUNNER_TEMP/export/KisaniCal.ipa" \
# --apiKey "${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}" \
# --apiIssuer "${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}"
# --- Option B: notarytool (for notarizing a macOS build, not iOS TestFlight) ---
# - name: Notarize
# run: |
# xcrun notarytool submit "$RUNNER_TEMP/export/KisaniCal.ipa" \
# --key ~/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}.p8 \
# --key-id "${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}" \
# --issuer "${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}" \
# --wait
- name: Notice
run: |
echo "IPA exported. TestFlight upload step is a commented-out placeholder."
echo "Add App Store Connect API-key secrets and uncomment Option A in release.yml."