59 Commits

Author SHA1 Message Date
Chad Curtis 6dcae6385a ci: use uniform PKCS12 password for signing keystore
packageRelease failed with 'Given final block not properly padded'
because the migrated PKCS12 entry was protected with the store password,
not the key password Gradle read from key.properties. Write the PKCS12
with a single uniform password ($KEY_PASSWORD) for store and entry, and
point both storePassword and keyPassword at it.
2026-06-02 03:39:54 -05:00
Chad Curtis 646ed9777f ci: pass alias key password to keytool keystore migration
The build-apk JKS->PKCS12 migration only supplied the store password,
so keytool prompted for the upload key's distinct password on the
non-interactive runner and failed with 'Too many failures - try later'.
Pass -srckeypass/-destkeypass ($KEY_PASSWORD) to match key.properties.
2026-06-02 03:07:04 -05:00
Chad Curtis f800d55451 Stop clobbering VITE_* CI vars with literal placeholders
The deploy-web job re-declared project-level CI/CD variables as `KEY: $KEY`.
When a source variable is out of scope for the job (e.g. a Protected variable
on an unprotected ref), GitLab leaves the reference unexpanded, so the literal
string "$VITE_TRANSLATE_WORKER_URL" got inlined into the build and surfaced in
the UI. Project-level variables are already in the job environment, so the
re-declaration is removed entirely.
2026-06-01 14:15:38 -05:00
Chad Curtis 7db479bb73 Wire VITE_PLAUSIBLE_DOMAIN and VITE_PLAUSIBLE_ENDPOINT into deploy-web 2026-05-27 03:05:35 -05:00
Chad Curtis 89f0aecbc1 ci: pass VITE_TRANSLATE_WORKER_URL into deploy-web build 2026-05-24 15:40:47 -05:00
Chad Curtis 1b4399df68 Rebrand app identifier and IPA name from Ditto to Agora
Renames the Capacitor app identifier from pub.agora.app to
spot.agora.app and cleans up Ditto-branded artifacts that don't refer
to upstream Ditto-the-project or Ditto-stack services.

App identifier (pub.agora.app -> spot.agora.app):
- capacitor.config.ts appId
- android applicationId, namespace, package_name string, custom_url_scheme
- iOS PRODUCT_BUNDLE_IDENTIFIER (Debug + Release)
- public/.well-known/assetlinks.json package_name
- public/.well-known/apple-app-site-association app id
- Info.plist BGTaskSchedulerPermittedIdentifiers and the matching
  Swift bgTaskIdentifier (previously mismatched: plist said
  pub.agora.app.notification-refresh, Swift said
  pub.ditto.app.notification-refresh, so background refresh would
  silently fail to register)
- src/lib/helpContent.ts Zapstore URLs
- .gitlab-ci.yml --package_name for fastlane supply

Android Java package (pub.ditto.app -> spot.agora.app):
- Move android/app/src/main/java/pub/ditto/app/ ->
  android/app/src/main/java/spot/agora/app/ (4 files: MainActivity,
  DittoNotificationPlugin, NostrPoller, NotificationRelayService)
- Update package declarations to match the new Android namespace
  (was a hard build failure with namespace = spot.agora.app)
- Update proguard -keep rule
- Update NotificationRelayService ACTION_FETCH intent string
  pub.ditto.app.ACTION_FETCH -> spot.agora.app.ACTION_FETCH

Fastlane (pub.ditto.app -> spot.agora.app):
- Appfile, Matchfile, Fastfile provisioning profile specifiers.
  Matchfile still points at Soapbox's certificates git repo; a new
  match repo with certs for spot.agora.app is required before iOS CI
  signing works.

IPA artifact name (Ditto.ipa -> Agora.ipa):
- Fastfile output_name and matching CI artifact paths
- .gitlab-ci.yml: artifacts/Ditto.ipa references and the GitLab
  Generic Packages path from /packages/generic/ditto/ ->
  /packages/generic/agora/ (matches how APK/AAB are already
  published). Existing release artifacts at the old path remain
  reachable; new releases land at the new path.

Release-notes script fallback (Ditto vX.Y.Z -> Agora vX.Y.Z):
- scripts/extract-release-notes.mjs fallback used as the App Store /
  Play Store 'What's New' blurb when a changelog section has no
  summary.

manifest.webmanifest:
- Update related_applications Play Store entry to spot.agora.app.
- Remove the iTunes related_applications entry that pointed at
  the existing Ditto App Store listing; not applicable to Agora
  until Agora has its own listing.

Capacitor sync incidentals:
- npm run cap:sync picked up @capacitor/barcode-scanner registration
  that had been missed in a prior plugin install
  (android/app/capacitor.build.gradle, capacitor.settings.gradle,
  ios/App/CapApp-SPM/Package.swift).

Intentionally NOT touched:
- ditto.json filename, DittoConfigSchema, DittoConfig, and JSDoc
  references to ditto.json. The config-system shape is shared with
  upstream Ditto by design.
- relay.ditto.pub, blossom.ditto.pub, ditto.pub/api/* and other
  Ditto-stack services Agora actively consumes.
- The DittoNotificationPlugin Android/iOS class name, the
  DittoNotification JS bridge name, ditto_notification_config
  SharedPreferences keys, ic_stat_ditto drawables, and the
  DittoBridgeViewController. Renaming requires a coordinated
  JS-side rename plus a SharedPreferences migration or existing
  users on the Ditto fork lose their notification config on upgrade.
- Ditto references in skill docs, NIP.md kind comments, README, and
  zapstore.yaml attribution \u2014 those correctly describe the upstream
  Ditto project that Agora forked from.

Follow-ups required before CI succeeds end-to-end (out of scope here):
- Stand up a new fastlane match git repo containing certs +
  provisioning profiles for spot.agora.app, or update Matchfile
  git_url to point at it.
- Register spot.agora.app in App Store Connect for team GZLTTH5DLM
  and create a new App Store listing.
- Create a new Google Play Console listing for spot.agora.app
  (package name is immutable per app on Play; the existing
  pub.agora.app listing cannot be reused).
- Re-publish to Zapstore under spot.agora.app so the URLs in
  helpContent.ts resolve.
2026-05-17 18:42:46 -05:00
Alex Gleason 5b8d2d5c06 Evict stale precache service worker from old Agora deployment
A previous version of Agora deployed at agora.spot shipped a precaching
service worker that is still controlling returning browsers and serving
them stale HTML/JS — they never see new deploys.

The fix has three parts:

1. public/sw.js — on activate, delete every Cache Storage entry the old
   SW left behind. This SW has no fetch handler, so once it takes over
   nothing re-populates the cache.

2. src/main.tsx — register /sw.js unconditionally on every web page load.
   Previously only usePushNotifications registered it, which meant users
   who never visited NotificationSettings stayed pinned to the old SW
   forever. Native (Capacitor) skips this — there is no stale SW on the
   filesystem origin.

3. .gitlab-ci.yml — the deploy-web rsync was excluding sw.js from the
   first pass and never re-adding it to the second pass, so deploys
   silently never updated sw.js. Now it ships in the second pass
   alongside index.html (after hashed assets land).
2026-05-17 13:48:24 -05:00
Alex Gleason e0024567ff ci: remove redundant build-web job
test + deploy-web already cover what build-web was doing — the test
stage validates the build via 'npm run test' (which runs vite build),
and deploy-web builds and ships the dist/ to the live site. Keeping
build-web around just burned a runner slot to produce a dist/ artifact
nobody consumed.
2026-05-17 13:41:37 -05:00
Alex Gleason 0316331fd2 Add deploy-web job to push to agora.spot on every main push
Mirrors the venus/rrsync pattern documented in GITLAB_DEPLOY.md and the
deploy job from the old agora-v1 repo. Requires DEPLOY_SSH_KEY and
DEPLOY_TARGET protected CI/CD variables, which have been migrated over
from soapbox-pub/agora-v1.
2026-05-17 13:35:45 -05:00
Alex Gleason 740fc1c63c Merge ditto/main into agora
Pulls in 387 commits from ditto/main while preserving Agora-specific
features. Where the two codebases diverged on the same concept, kept
the Agora side per project direction.

Kept Agora-specific:
- SparkWallet stack (over Ditto's nostr-derived Bitcoin wallet)
- Communities (NIP-72 + chat + members), Messages, Organizers,
  Actions, Verified, Appearance settings
- DMProviderWrapper, country/organizer moderation in NoteMoreMenu
- 'Agora' branding, pub.agora.app bundle ID, version 2.8.0
- Built-in theme system (src/themes.ts) only

Rejected from Ditto:
- All Blobbi virtual pet code (80+ files, route, provider, sidebar,
  kind labels, feed setting, NIP.md entries, CSS animations)
- Custom theme events (kinds 36767/16767) — ThemesPage, ThemeContent,
  active profile themes, theme snapshot recovery
- On-chain zaps (kind 8333) and the entire Bitcoin wallet implementation
  (useBitcoinWallet, bitcoin-signers, BitcoinContentHeader,
  bitcoinjs-lib / @bitcoinerlab/secp256k1 / ecpair / tiny-secp256k1)
- ZapSuccessScreen (depended on dropped bitcoin lib)

Pulled in from Ditto:
- .agents/skills/* (12 new specialized skills, slim AGENTS.md)
- @nostrify bumps to 0.52 / 0.6 / 0.37
- New routes/pages: Music, Podcasts, Videos, Vines, Wikipedia, Books,
  Bluesky, Archive, AIChat, Trends, Webxdc, Highlights, Decks, Emojis,
  Development, Treasures, Colors, Packs
- Birdstar feed integration (kinds 2473, 12473, 30621)
- Wikipedia/Wikidata/Scryfall lookup in ExternalContentPage
- release-notes CI job + extract-release-notes.mjs script
- nsite:// URI handling in feed/sidebar
- iOS fastlane setup
- src/lib/avatarShape.ts + Avatar shape prop (kept for new Music/People
  components that depend on it)

Preserved Agora's ABSOLUTE 'NEVER COMMIT' rule at the top of AGENTS.md
and dropped Ditto's contradicting 'Commit at the end of every task'
section.

Validation: npm run test passes (tsc, eslint, 40/40 vitest, vite build).
2026-05-13 18:35:03 -05:00
Alex Gleason f5bb8afaec Run publish-app-store on the Mac runner instead of Linux
fastlane's deliver action invokes Apple's iTMSTransporter / altool to
push the IPA to App Store Connect, and those tools only ship inside
Xcode. On a generic ruby:3.3 Linux container the upload step crashed
with 'No such file or directory @ dir_chdir0' from
JavaTransporterExecutor#execute, because Helper.itms_path resolved
to a missing Xcode path.

Move publish-app-store onto the same self-hosted Mac runner as
build-ipa (tags: [macos]), drop the now-unnecessary 'gem install
fastlane' (the Mac has it on PATH via ~/.bash_profile), and unset
APP_STORE_CONNECT_API_KEY_PATH to mirror build-ipa's defense against
fastlane's env-var collision (match expects a JSON descriptor there;
we pass the API key inline via the Fastfile).

Update AGENTS.md and the release / ci-cd-publishing / mac-runner
skills, which all incorrectly described publish-app-store as a
Linux-only API call.

Regression-of: b8773c47
2026-05-11 14:00:13 -07:00
Alex Gleason d044218c6a Use a release-summary paragraph for App Store, Play Store, and the in-app toast
Each CHANGELOG.md release section now begins with a single plaintext
paragraph (max ~500 chars) before any `### Category` heading. That
paragraph drives the release blurb in three storefronts and the
in-app version-update toast, so we no longer ship a marketing-grade
description in one place and a raw bullet list in another.

scripts/extract-release-notes.mjs is the single source of truth for
extraction. It emits the full section (summary + lists) by default
and only the summary paragraph with --summary, with a
`Ditto vX.Y.Z` fallback for legacy entries that have no summary.

CI changes:
- New `release-notes` job (build stage, default node:22 image)
  produces `artifacts/release-notes.md` and
  `artifacts/release-notes-summary.txt` once per pipeline.
- `release` job pulls release-notes.md as the GitLab Release
  description (replaces the old inline awk extraction). It now uses
  `needs:` with `artifacts: false` for build-apk/build-ipa to
  avoid re-downloading the .apk/.aab/.ipa it doesn't open.
- `publish-app-store` copies release-notes-summary.txt to
  `ios/fastlane/metadata/en-US/release_notes.txt` (replaces its
  own awk extraction).
- `publish-google-play` drops `--skip_upload_changelogs`, writes
  the summary to
  `android/fastlane/metadata/android/en-US/changelogs/<versionCode>.txt`
  and points fastlane supply at `--metadata_path`. This is the
  first time we upload a What's New text to the Play Store from CI.

App-side changes:
- `src/lib/changelog.ts` parser captures the leading non-blank
  paragraph (before any bullet or category heading) into
  `entry.summary`.
- `VersionCheck.tsx` toast uses `entry.summary` when present,
  falling back to the legacy 60-char first-bullet excerpt for
  backward compatibility.
- `ChangelogPage` renders the summary as a lede paragraph above
  the bullet list in both LatestRelease and ChangelogEntryCard.

Changelog content:
- Added summary paragraphs to v2.14.3, v2.14.2, v2.14.1.

Skill + AGENTS.md updates:
- `release` skill documents the summary paragraph format, the
  500-char convention, and the seven-job pipeline.
- `ci-cd-publishing` skill gains a 'Release notes pipeline' section
  mapping each storefront to its source artifact.
- AGENTS.md pipeline summary mentions release-notes and the summary
  flow into both store "What's new" fields.
2026-05-11 13:13:33 -07:00
Alex Gleason b8773c47d7 Automate App Store releases via self-hosted Mac runner
Mirror the existing Android publishing flow for iOS. The pipeline
gains two jobs: build-ipa runs on a self-hosted Mac runner and
produces a signed App Store IPA; publish-app-store runs on a shared
Linux runner and submits the prebuilt IPA to App Store Connect.

Build pipeline (.gitlab-ci.yml):
- build-ipa (Mac, stage build, parallel with build-apk): decodes the
  ASC API key, runs match (with api_key, so cert validity is verified
  against Apple before xcodebuild starts), builds web assets, syncs
  Capacitor, stamps MARKETING_VERSION. Uploads Ditto-${CI_COMMIT_TAG}
  .ipa to GitLab's Generic Packages registry.
- publish-app-store (Linux ruby:3.3, needs: [build-ipa]): gem
  install fastlane, decode the ASC API key, extract the changelog
  section into release_notes.txt, fastlane submit_release with
  IPA_PATH pointing at the inherited artifact. No Xcode, no signing,
  no keychain \u2014 pure Apple API call.
- release job now needs both build-apk and build-ipa, and links three
  assets (APK / AAB / IPA).

fastlane (ios/fastlane/Fastfile, Matchfile, Appfile, metadata/):
- Four lanes: build_ipa (CI build), submit_release (CI publish, reads
  IPA_PATH from env), release (single-step convenience for local
  dev), submit_only (debug lane to re-submit an already-uploaded
  build).
- Match config points at the private gitlab.com/soapbox-pub
  /certificates repo. App Store Connect API key is built inline in
  the Fastfile to avoid a collision with match's APP_STORE_CONNECT
  _API_KEY_PATH env var (match wants a JSON descriptor, the action
  writes a raw .p8). CI overrides CODE_SIGN_STYLE=Manual via xcargs
  so the Xcode project can stay on Automatic for local development.

Vite config (vite.config.ts):
- Renames the build-time config override env var from CONFIG_FILE to
  DITTO_CONFIG_FILE. GitLab Runner sets CONFIG_FILE to its own TOML
  config in job env, which broke vite's loader.

App-side changes:
- ios/App/App.xcodeproj/project.pbxproj: team GZLTTH5DLM stamped in;
  MARKETING_VERSION gets stamped from the tag at build time.
- public/CHANGELOG.md, package.json: v2.14.3.

Skills + AGENTS.md updated to reflect the six-job pipeline (test /
deploy unchanged, build now has two jobs, release / publish updated)
and to document Mac-runner operations, fastlane match cert rotation,
and local debugging workflows.
2026-05-11 12:59:04 -07:00
sam 0c389397d2 disable nsite publishing for now 2026-04-19 15:40:21 +05:45
sam 9550094ffb wip mega dump/migration from ditto 2026-04-17 12:10:11 +05:45
Alex Gleason 4245b2aede Add Google Play publishing to CI release pipeline 2026-04-11 18:10:29 -05:00
Alex Gleason 3cdec3ceb6 Add more Zapstore publish relays to CI 2026-04-11 17:57:13 -05:00
Alex Gleason f25139103c Add native SandboxPlugin for iOS and Android 2026-04-08 20:47:28 -05:00
Alex Gleason 594e7ea8fa ci: add build-web job to produce downloadable artifact
The old 'pages' job was removed when deploying switched to nsite,
which broke the artifact download URL on the docs site. This adds
a new build-web job that builds the web app on main and saves the
dist/ directory as a downloadable artifact.
2026-04-06 01:09:10 -05:00
Alex Gleason a261934ab0 ci: publish zsp to relay.ditto.pub and use blossom.ditto.pub; remove --publish-server-list from nsite 2026-04-02 22:48:46 -05:00
Alex Gleason d0b5164e6d Deploy nsite as named site 'ditto' and drop publish-relay-list 2026-03-31 21:01:47 -05:00
Alex Gleason defc39c0f3 Replace GitLab Pages deploy with nsite deploy via nsyte
Use nsyte CLI with NIP-46 nbunksec bunker credential to deploy
the web app to nsite on every default branch push. Downloads the
nsyte binary, builds the Vite app, and uploads to configured
Blossom servers and Nostr relays with SPA fallback routing.
2026-03-31 20:29:29 -05:00
Alex Gleason 0d4a96e785 Fix zapstore publish: replace removed -y flag with --quiet
zsp v0.4.5 renamed the -y flag to --quiet. The old flag caused
the publish command to fail silently (exit 0 with usage printed
to stderr), so the CI job appeared to succeed.
2026-03-31 17:23:22 -05:00
Alex Gleason 6e2589e125 fix: use project-relative path for release notes file 2026-03-26 23:57:24 -05:00
Alex Gleason 89fe5b8937 fix: use native release: keyword instead of glab to fix 403 permission error 2026-03-26 23:42:04 -05:00
Alex Gleason 3126ad2380 fix: pass CI_JOB_TOKEN to glab in release job 2026-03-26 23:02:06 -05:00
Alex Gleason 4ac8651cc8 fix: use glab directly for releases instead of dotenv artifact
GitLab's dotenv artifact format doesn't support multi-line heredoc
values, causing the release job to fail with 400 Bad Request. The
release-cli image already includes glab, so use it directly with
--notes-file to pass multi-line changelog content safely.
2026-03-26 21:50:57 -05:00
Alex Gleason cbbb576b26 Add release system with semver versioning, changelog, and release skill
- Switch from CalVer (date+SHA) to semantic versioning starting at v2.0.0
- Create release skill (.agents/skills/release/) with full AI-guided release workflow
- Add CHANGELOG.md with initial 2.0.0 entry
- Update CI tag regex to match semver tags (v2.0.0 instead of v2026.03.24-sha)
- Extract changelog content into GitLab release descriptions
- Update Android versionName to 2.0.0 in build.gradle
- Update iOS MARKETING_VERSION to 2.0.0 in pbxproj
- Expose VERSION (semver) and BUILD_DATE (ISO 8601) as build-time constants
- Display version and build date in Settings page footer
- Remove npm release script (releases are now done via the AI skill)
2026-03-26 21:15:35 -05:00
Alex Gleason d02b661bed Build and publish AAB alongside APK in CI pipeline 2026-03-18 14:20:35 -05:00
Chad Curtis 756eabd9fb fix: use CI_COMMIT_TAG as package version path to avoid empty variable expansion in release-cli 2026-03-16 05:02:44 -05:00
Chad Curtis 76abc846d0 fix: upload APK to Generic Packages registry for stable release URL 2026-03-16 04:53:48 -05:00
Chad Curtis 94b63a7637 fix: use static APK filename so artifacts.paths variable expansion works 2026-03-16 04:46:14 -05:00
Chad Curtis caa3bff6b0 fix: escape colons in publish-zapstore script to fix GitLab CI YAML validation 2026-03-16 03:59:40 -05:00
Chad Curtis 7034c54bbb Fix zapstore publish version by injecting tag into zapstore.yaml 2026-03-16 03:34:50 -05:00
Chad Curtis 487e32d5ac Fix release artifact URL: use - instead of + in tag format
The + character in git tags breaks GitLab's artifact download URL.
Switch tag format from v2026.03.16+abc1234 to v2026.03.16-abc1234
so the artifact URL works without any encoding workarounds.
2026-03-16 03:22:57 -05:00
Chad Curtis 6e62d172c0 Upload APK to Generic Packages registry for stable release download URL
The job artifact URL with + in the tag name returns 404. Upload the APK
to the Generic Packages registry during build, then link to that stable
public URL in the GitLab release.
2026-03-16 03:22:09 -05:00
Chad Curtis ce34f14bf3 Remove broken APK artifact link from release — available via Zapstore 2026-03-16 03:21:13 -05:00
Chad Curtis c03dda00f6 Fix release APK artifact URL to use API endpoint 2026-03-16 03:12:50 -05:00
Chad Curtis b81e44e393 Revert zapstore version stamping — zsp reads version from APK directly 2026-03-16 03:02:02 -05:00
Chad Curtis a2124d25ee Stamp version into zapstore.yaml during CI build 2026-03-16 02:58:37 -05:00
Chad Curtis 93ce7d548b Remove --silent from npm ci to surface install errors 2026-03-16 02:48:41 -05:00
Chad Curtis 3809d4b72d Restore version comments, drop versionCode explanation 2026-03-16 02:44:53 -05:00
Chad Curtis 25032b0365 Remove dead comment from build-apk version block 2026-03-16 02:44:42 -05:00
Chad Curtis 6cc7833497 Fix versionCode: use CI_PIPELINE_IID instead of git rev-list
git is not installed in the eclipse-temurin:21-jdk build image.
CI_PIPELINE_IID is a GitLab built-in variable (per-project pipeline
counter) that is always monotonically increasing and requires no
external tools.
2026-03-16 02:44:30 -05:00
Chad Curtis 393a9b6621 Fix versionCode to use commit count so same-day releases are unique
Previously versionCode was derived from the date only (20260316), so two
releases on the same day got the same code and Zapstore/Android would
reject the second as a duplicate. Switch to git rev-list --count HEAD
which is monotonically increasing and guaranteed unique per build.

versionName now uses the full calver+sha tag (e.g. 2026.03.16+9ddecb5)
instead of just the date portion.
2026-03-16 02:19:32 -05:00
Alex Gleason 30ca446c67 Persist NIP-46 client key in Zapstore CI job for stable bunker auth 2026-03-14 23:58:35 -05:00
Alex Gleason 1b77712e72 Add Zapstore publishing to CI pipeline 2026-03-14 22:00:08 -05:00
Chad Curtis 351c92d33e Remove generate-icons step from APK CI build 2026-02-27 04:56:53 -06:00
Chad Curtis 015a3a7e3f Fix Android app name capitalization to Ditto
- Update strings.xml to use 'Ditto' instead of 'ditto'
- Update capacitor.config.ts appName to 'Ditto'
- Update GitLab CI/CD artifact naming to use 'Ditto-' prefix
- Ensures consistency with web version branding
2026-02-25 00:01:41 +00:00
Chad Curtis f18a64cb08 Use inkscape instead of rsvg-convert for SVG rendering 2026-02-24 05:05:54 -06:00