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
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.cs]
indent_style = tab
indent_size = 4

[*.{yml,yaml,json,md,sh}]
indent_style = space
indent_size = 2
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Summary

- What does this change do?

## Checklist

- [ ] No secrets committed
- [ ] Built wrapper: `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh`
- [ ] Collected SDK xcframeworks: `bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh`
- [ ] Packed NuGet: `dotnet pack src/Kapusch.FacebookApisForiOSComponents/Kapusch.FacebookApisForiOSComponents.csproj -c Release -o artifacts/nuget`
- [ ] Updated docs if behavior/integration changed
96 changes: 96 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: ci

on:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
build_pack_ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"

- name: Install iOS workload
run: |
dotnet workload install ios

- name: Cache NuGet
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('global.json', '**/*.csproj') }}

- name: Cache SwiftPM scratch
uses: actions/cache@v4
with:
path: |
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build/spm
key: ${{ runner.os }}-swiftpm-${{ hashFiles('src/Kapusch.FacebookApisForiOSComponents/Native/iOS/KapuschFacebookAuthInterop/Package.resolved') }}

- name: Build iOS wrapper
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh

- name: Collect Facebook xcframeworks
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh

- name: Pack
run: |
dotnet pack src/Kapusch.FacebookApisForiOSComponents/Kapusch.FacebookApisForiOSComponents.csproj \
-c Release \
-o artifacts/nuget

- name: Validate nupkg layout
run: |
python3 - <<'PY'
import glob, sys, zipfile

nupkgs = glob.glob("artifacts/nuget/*.nupkg")
if not nupkgs:
print("ERROR: no .nupkg found under artifacts/nuget/")
sys.exit(1)

nupkg = sorted(nupkgs)[-1]
print(f"Validating {nupkg}")

z = zipfile.ZipFile(nupkg)
names = set(z.namelist())

required = [
"buildTransitive/Kapusch.Facebook.iOS.targets",
"kfb.xcframework/Info.plist",
"fb/FBAEMKit.xcframework/Info.plist",
"fb/FBSDKCoreKit.xcframework/Info.plist",
"fb/FBSDKCoreKit_Basics.xcframework/Info.plist",
"fb/FBSDKGamingServicesKit.xcframework/Info.plist",
"fb/FBSDKLoginKit.xcframework/Info.plist",
"fb/FBSDKShareKit.xcframework/Info.plist",
]

missing = [p for p in required if p not in names]
if missing:
print("ERROR: missing required paths in nupkg:")
for p in missing:
print(f" - {p}")
sys.exit(1)

# Guardrail: ensure the wrapper is not flattened at the package root.
if "Info.plist" in names:
print("ERROR: wrapper appears flattened (found 'Info.plist' at package root).")
sys.exit(1)

print("OK: nupkg layout looks correct.")
PY

- uses: actions/upload-artifact@v4
with:
name: nuget
path: artifacts/nuget/*.nupkg
122 changes: 122 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: publish

on:
workflow_dispatch:
push:
tags:
- "v*"

permissions:
contents: read
packages: write

jobs:
pack_and_publish:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Determine package version
id: version
shell: bash
run: |
if [[ "${{ github.ref }}" =~ ^refs/tags/v ]]; then
REF="${{ github.ref }}"
VERSION="${REF#refs/tags/v}"
else
CSPROJ="src/Kapusch.FacebookApisForiOSComponents/Kapusch.FacebookApisForiOSComponents.csproj"
BASE_VERSION=$(grep -oE '<Version>[^<]+' "$CSPROJ" | head -n 1 | sed 's/<Version>//' || echo "0.1.0")
COMMIT_SHORT=$(git rev-parse --short HEAD)
RUN_NUMBER="${{ github.run_number }}"
VERSION="${BASE_VERSION}-prerelease.${RUN_NUMBER}.${COMMIT_SHORT}"
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Package version: ${VERSION}"

- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"

- name: Install iOS workload
run: |
dotnet workload install ios

- name: Cache NuGet
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('global.json', '**/*.csproj') }}

- name: Cache SwiftPM scratch
uses: actions/cache@v4
with:
path: |
src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build/spm
key: ${{ runner.os }}-swiftpm-${{ hashFiles('src/Kapusch.FacebookApisForiOSComponents/Native/iOS/KapuschFacebookAuthInterop/Package.resolved') }}

- name: Build iOS wrapper
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh

- name: Collect Facebook xcframeworks
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh

- name: Pack
run: |
dotnet pack src/Kapusch.FacebookApisForiOSComponents/Kapusch.FacebookApisForiOSComponents.csproj \
-c Release \
-o artifacts/nuget \
/p:PackageVersion="${{ steps.version.outputs.version }}"

- name: Validate nupkg layout
run: |
python3 - <<'PY'
import glob, sys, zipfile

nupkgs = glob.glob("artifacts/nuget/*.nupkg")
if not nupkgs:
print("ERROR: no .nupkg found under artifacts/nuget/")
sys.exit(1)

nupkg = sorted(nupkgs)[-1]
print(f"Validating {nupkg}")

z = zipfile.ZipFile(nupkg)
names = set(z.namelist())

required = [
"buildTransitive/Kapusch.Facebook.iOS.targets",
"kfb.xcframework/Info.plist",
"fb/FBAEMKit.xcframework/Info.plist",
"fb/FBSDKCoreKit.xcframework/Info.plist",
"fb/FBSDKCoreKit_Basics.xcframework/Info.plist",
"fb/FBSDKGamingServicesKit.xcframework/Info.plist",
"fb/FBSDKLoginKit.xcframework/Info.plist",
"fb/FBSDKShareKit.xcframework/Info.plist",
]

missing = [p for p in required if p not in names]
if missing:
print("ERROR: missing required paths in nupkg:")
for p in missing:
print(f" - {p}")
sys.exit(1)

if "Info.plist" in names:
print("ERROR: wrapper appears flattened (found 'Info.plist' at package root).")
sys.exit(1)

print("OK: nupkg layout looks correct.")
PY

- name: Push to GitHub Packages
env:
NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
dotnet nuget push artifacts/nuget/*.nupkg \
--api-key "$NUGET_AUTH_TOKEN" \
--source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \
--skip-duplicate
74 changes: 74 additions & 0 deletions .github/workflows/sample-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: sample-ios (manual)

on:
workflow_dispatch:

permissions:
contents: read

jobs:
build_sample_ios:
runs-on: macos-15
env:
DOTNET_MULTILEVEL_LOOKUP: 0
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: true
DOTNET_CLI_WORKLOAD_UPDATE_NOTIFICATION_LEVEL: Disable

steps:
- uses: actions/checkout@v4

- name: Setup Xcode 26.0
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "26.0"

- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"

- name: Pin workload update mode (manifests)
shell: bash
run: |
dotnet workload config --update-mode manifests
dotnet workload config --update-mode

- name: Purge incompatible iOS packs (cache defense)
shell: bash
run: |
set -euo pipefail
PACKS_DIR="$HOME/.dotnet/packs"
for v in 26.2; do
if [ -d "$PACKS_DIR" ] && compgen -G "$PACKS_DIR/Microsoft.iOS.*_${v}*" > /dev/null; then
echo "Removing cached iOS ${v} packs from $PACKS_DIR"
rm -rf "$PACKS_DIR"/Microsoft.iOS.*_${v}*
fi
done

- name: Install iOS workload
shell: bash
run: |
dotnet workload install ios --skip-manifest-update

- name: Diagnostics (.NET + workloads)
shell: bash
run: |
dotnet --info
dotnet workload list

- name: Build iOS wrapper
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/build.sh

- name: Collect Facebook xcframeworks
run: |
bash src/Kapusch.FacebookApisForiOSComponents/Native/iOS/collect-facebook-xcframeworks.sh

- name: Build iOS sample (simulator, no signing)
run: |
dotnet build samples/Kapusch.Facebook.iOS.Sample/Kapusch.Facebook.iOS.Sample.csproj \
-c Debug \
-p:RuntimeIdentifier=iossimulator-arm64 \
-p:EnableCodeSigning=false

31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# .NET
bin/
obj/
*.user
*.suo
*.userosscache
*.sln.docstates

# NuGet
*.nupkg
*.snupkg
artifacts/

# macOS
.DS_Store

# SwiftPM / Xcode
.build/
*.xcworkspace/
DerivedData/

# Local caches used by buildTransitive restore
.kapusch/

# Native build output (repo-only)
src/**/Native/iOS/build/

# Sample local config
samples/**/Info.plist
samples/**/GoogleService-Info.plist
samples/**/secrets.*
21 changes: 21 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Kapusch.FacebookApisForiOSComponents — AI Working Agreement

## Goals
- Produce a reproducible iOS NuGet package for Facebook Login interop.
- Do not commit secrets.

## Packaging constraints
- Public OSS repo: keep docs/sample generic and not app-specific.
- The NuGet ships the required `xcframework`s and references them via `NativeReference`.
- Consuming apps must not download native deps at build time.
- The repo may use SwiftPM during CI/build to fetch the upstream Facebook iOS SDK, but consuming apps must not download native deps at build time.

## Repo layout
- `src/Kapusch.FacebookApisForiOSComponents/` — NuGet project (managed API + buildTransitive MSBuild)
- `src/Kapusch.FacebookApisForiOSComponents/Native/iOS/` — Swift wrapper source + scripts (repo-only)
- `Docs/` — integration docs
- `samples/` — optional sample template (no secrets committed)

## Safety
- Do not add new dependency ingestion paths without documenting them in `README.md`.
- Do not commit real app ids/secrets.
Loading