diff --git a/README.de.md b/README.de.md index d720361..d9c605b 100644 --- a/README.de.md +++ b/README.de.md @@ -237,6 +237,8 @@ Hinweise für Beiträge und den DCO-Sign-off stehen in [CONTRIBUTING.md](CONTRIBUTING.md). Der [Verhaltenskodex](CODE_OF_CONDUCT.md) regelt die Zusammenarbeit, die [Security Policy](SECURITY.md) die vertrauliche Meldung von Schwachstellen. +Der [öffentliche Release-Prozess](RELEASING.md) beschreibt Versionierung, +Prüfungen und reproduzierbare Release-Artefakte. [Datenschutz](PRIVACY.md), [Nutzungsbedingungen](TERMS.md) und der [Hinweis](NOTICE) dokumentieren Datenfluss und Lizenzgrenzen. diff --git a/README.md b/README.md index c8a521d..1b65aa6 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,8 @@ SourceBraid is fully open source under the [MIT License](LICENSE). See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidance and DCO sign-off, the [Code of Conduct](CODE_OF_CONDUCT.md) for community standards, and the [Security Policy](SECURITY.md) for private vulnerability reporting. The +[public release process](RELEASING.md) documents versioning, validation, and +reproducible release artifacts. The [privacy notice](PRIVACY.md), [terms](TERMS.md), and [notice](NOTICE) document the local, user-controlled data flow and licensing boundaries. diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..d3d6d9b --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,136 @@ +# Releasing SourceBraid + +This document describes the reproducible, public part of a SourceBraid release. +Store credentials, account verification, legal attestations, review accounts, +and final submission decisions are intentionally maintained outside the public +repository. + +No Chrome Web Store, ChatGPT/Codex directory, or App Store release has been +published yet. The first coordinated public release should use `1.0.0` as its +customer-facing version unless the maintainers document a different decision. + +## Release principles + +- Build and tag releases from a clean commit on the public `main` branch. +- Never merge private repository history into this repository. +- Never include `website/`, `web-clips/`, credentials, local configuration, + Keychain data, caches, indexes, or generated build directories in a release. +- Use the checked-in package builders. They construct archives from explicit + allowlists instead of copying the repository broadly. +- Preserve source provenance and use only synthetic or redistributable content + in release screenshots and examples. +- Every pull-request commit must carry a DCO `Signed-off-by:` trailer. + +## Version alignment + +Before creating the first release candidate, align these customer-facing +versions: + +- Chrome: `version` in `manifest.json`. +- ChatGPT/Codex skills package: `version` in + `codex-plugin/sourcebraid/.codex-plugin/plugin.json`. +- iOS app and Share Extension: `MARKETING_VERSION` in + `ios/SourceBraid.xcodeproj/project.pbxproj`. + +Chrome versions use one to four dot-separated integers. The plugin uses semantic +versioning. After the first iOS upload, increase `CURRENT_PROJECT_VERSION` for +every new binary while keeping the app and Share Extension build numbers equal. + +The first iOS publication uses the SourceBraid identities: + +- app: `de.patrickschiller.sourcebraid`; +- Share Extension: `de.patrickschiller.sourcebraid.share`; +- App Group: `group.de.patrickschiller.sourcebraid`; +- shared Keychain group: + `$(AppIdentifierPrefix)de.patrickschiller.sourcebraid.shared`. + +## Preflight checks + +Run from the repository root: + +```bash +git status --short --branch +node --test tests/capture-utils.test.js +python3 -m unittest discover -s tests -p "test_*.py" +``` + +Run the unsigned iOS build from `ios/`: + +```bash +xcodebuild \ + -project SourceBraid.xcodeproj \ + -scheme SourceBraid \ + -sdk iphonesimulator \ + -destination 'generic/platform=iOS Simulator' \ + CODE_SIGNING_ALLOWED=NO \ + build +``` + +Do not release while a required check fails or the worktree contains unrelated +changes. + +## Chrome package + +Build the Manifest V3 archive from its explicit allowlist: + +```bash +python3 scripts/build_chrome_package.py +unzip -l dist/sourcebraid-chrome-v*.zip +``` + +The script prints the package path, version, SHA-256 digest, and file count. The +ZIP must contain `manifest.json` at its root and must not contain source archives, +the private website, plugin configuration, iOS sources, tests, Git metadata, or +local settings. + +## ChatGPT and Codex skills package + +Build the initial skills-only archive: + +```bash +python3 scripts/build_plugin_package.py +unzip -l dist/sourcebraid-plugin-skills-v*.zip +``` + +The public package contains the three SourceBraid skills, their OpenAI metadata, +the dependency-free CLI, and listing assets. The builder intentionally removes +the local MCP server declaration and app entries from the packaged manifest. +Local repository installations can continue to use the complete plugin source. + +## iOS archive + +Confirm that the SourceBraid bundle identifiers, App Group, and Keychain access +group are registered for the selected Apple Developer team before enabling +signing. First validate the unsigned simulator build above. Then use the archive +and export commands in [`ios/README.md`](ios/README.md). + +Signing and App Store upload credentials are not part of this repository. Never +commit provisioning profiles, certificates, export credentials, review tokens, +or App Store Connect API keys. + +## GitHub setup script + +Validate the user-facing repository bootstrap workflow without changing a +repository: + +```bash +python3 scripts/setup_github.py --repo OWNER/REPOSITORY --dry-run +``` + +The setup script must continue to refuse public archive repositories, preserve +existing files, avoid printing credentials, and upload only its documented +allowlist. + +## Tag and publish artifacts + +1. Review the complete diff from the previous release tag, or the repository + root commit for the first release. +2. Record the passing check results and package SHA-256 digests. +3. Create an annotated version tag on the reviewed public commit. +4. Push the tag to the public repository. +5. Attach the Chrome and skills ZIP files and their digests to the corresponding + GitHub release when binary artifacts are distributed there. +6. Verify that every published archive can be traced back to the tagged commit. + +Store review and publication remain separate maintainer actions. A GitHub tag or +release must not imply that a store submission has already been approved. diff --git a/ios/README.md b/ios/README.md index d0b514d..a7e3ecc 100644 --- a/ios/README.md +++ b/ios/README.md @@ -8,8 +8,8 @@ The iOS project contains a SwiftUI configuration app and a native Share Extensio 2. Select the **SourceBraid** project and the **SourceBraid** target. 3. Under **Signing & Capabilities**, select your Apple Developer team. 4. Repeat for the **SourceBraidShare** target. -5. The existing TestFlight app keeps its pre-rebrand bundle identifiers `de.patrickschiller.stowmark` and `de.patrickschiller.stowmark.share`; changing them would create a different app instead of an update. -6. Keep the pre-rebrand App Group identical in both targets: `group.de.patrickschiller.stowmark`. This preserves settings and Keychain access across the SourceBraid rename. +5. Register or select the SourceBraid bundle identifiers `de.patrickschiller.sourcebraid` and `de.patrickschiller.sourcebraid.share`. +6. Register the App Group `group.de.patrickschiller.sourcebraid`, enable it for both targets, and keep the shared Keychain access group aligned with the entitlements. 7. Run the SourceBraid app on your iPhone once and configure GitHub. The fine-grained GitHub token needs `Contents: Read and write` for the private SourceBraid repository. It is stored in a Keychain access group shared only by the app and extension. @@ -38,9 +38,9 @@ xcodebuild \ -allowProvisioningUpdates ``` -The export options upload the archive directly to App Store Connect. The existing -app record uses bundle ID `de.patrickschiller.stowmark`; its customer-facing name -is **SourceBraid**. +The export options upload the archive directly to App Store Connect. Create the +initial app record with bundle ID `de.patrickschiller.sourcebraid` and the +customer-facing name **SourceBraid** before the first upload. ## Use diff --git a/ios/SourceBraid.xcodeproj/project.pbxproj b/ios/SourceBraid.xcodeproj/project.pbxproj index e99fa28..b6aa92c 100644 --- a/ios/SourceBraid.xcodeproj/project.pbxproj +++ b/ios/SourceBraid.xcodeproj/project.pbxproj @@ -462,7 +462,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 0.2.0; - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -490,7 +490,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 0.2.0; - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; @@ -516,7 +516,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = 0.2.0; - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark.share; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid.share; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -543,7 +543,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = 0.2.0; - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark.share; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid.share; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -566,7 +566,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark.tests; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = iphonesimulator; SWIFT_VERSION = 5.0; @@ -586,7 +586,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.stowmark.tests; + PRODUCT_BUNDLE_IDENTIFIER = de.patrickschiller.sourcebraid.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = iphonesimulator; SWIFT_VERSION = 5.0; diff --git a/ios/SourceBraid/Resources/Info.plist b/ios/SourceBraid/Resources/Info.plist index 4bdbf0d..a46768c 100644 --- a/ios/SourceBraid/Resources/Info.plist +++ b/ios/SourceBraid/Resources/Info.plist @@ -23,7 +23,7 @@ ITSAppUsesNonExemptEncryption SourceBraidKeychainAccessGroup - $(AppIdentifierPrefix)de.patrickschiller.stowmark.shared + $(AppIdentifierPrefix)de.patrickschiller.sourcebraid.shared UILaunchScreen UISupportedInterfaceOrientations diff --git a/ios/SourceBraid/Resources/SourceBraid.entitlements b/ios/SourceBraid/Resources/SourceBraid.entitlements index 3e1e535..e6d1349 100644 --- a/ios/SourceBraid/Resources/SourceBraid.entitlements +++ b/ios/SourceBraid/Resources/SourceBraid.entitlements @@ -4,11 +4,11 @@ com.apple.security.application-groups - group.de.patrickschiller.stowmark + group.de.patrickschiller.sourcebraid keychain-access-groups - $(AppIdentifierPrefix)de.patrickschiller.stowmark.shared + $(AppIdentifierPrefix)de.patrickschiller.sourcebraid.shared diff --git a/ios/SourceBraid/Shared/SourceBraidEnvironment.swift b/ios/SourceBraid/Shared/SourceBraidEnvironment.swift index 4c51561..420ff26 100644 --- a/ios/SourceBraid/Shared/SourceBraidEnvironment.swift +++ b/ios/SourceBraid/Shared/SourceBraidEnvironment.swift @@ -2,8 +2,8 @@ import Foundation enum SourceBraidEnvironment { // Keep the pre-rebrand identifiers so TestFlight upgrades retain settings and credentials. - static let appGroupIdentifier = "group.de.patrickschiller.stowmark" - static let keychainService = "de.patrickschiller.stowmark" + static let appGroupIdentifier = "group.de.patrickschiller.sourcebraid" + static let keychainService = "de.patrickschiller.sourcebraid" static let keychainAccount = "github-token" static let recentCapturesKey = "recent-captures" diff --git a/ios/SourceBraidShare/Info.plist b/ios/SourceBraidShare/Info.plist index a0553d2..79e9158 100644 --- a/ios/SourceBraidShare/Info.plist +++ b/ios/SourceBraidShare/Info.plist @@ -19,7 +19,7 @@ CFBundleVersion $(CURRENT_PROJECT_VERSION) SourceBraidKeychainAccessGroup - $(AppIdentifierPrefix)de.patrickschiller.stowmark.shared + $(AppIdentifierPrefix)de.patrickschiller.sourcebraid.shared NSExtension NSExtensionAttributes diff --git a/ios/SourceBraidShare/SourceBraidShare.entitlements b/ios/SourceBraidShare/SourceBraidShare.entitlements index 3e1e535..e6d1349 100644 --- a/ios/SourceBraidShare/SourceBraidShare.entitlements +++ b/ios/SourceBraidShare/SourceBraidShare.entitlements @@ -4,11 +4,11 @@ com.apple.security.application-groups - group.de.patrickschiller.stowmark + group.de.patrickschiller.sourcebraid keychain-access-groups - $(AppIdentifierPrefix)de.patrickschiller.stowmark.shared + $(AppIdentifierPrefix)de.patrickschiller.sourcebraid.shared