Hello! This is the public repo of the mParticle Web SDK. We've built the mParticle platform to take a new approach to web and mobile app data and the platform has grown to support 300+ integrations including analytics, data warehouses, and marketing automation. mParticle is designed to serve as the connector between all of these services - check out our site, or hit us at developers@mparticle.com to learn more.
Fully detailed documentation and other information about mParticle web SDK can be found at our doc site here
Version 3 of the mParticle Web SDK is generally available. See MIGRATING.md for the in-repo upgrade steps, the 3.0.0 changelog for the full commit list, and the Upgrade to Version 3 guide on the docs site.
There are two ways to initialize the SDK, either via a script tag, or you can bundle the SDK via NPM. A summary of steps for both is available below, but you should review the detailed documentation for the script tag and self hosting on the mParticle docs site.
To integrate the SDK add the following snippet to your site after customizing mParticle.config, ideally in the <head> element. Replace REPLACE WITH API KEY at the end of the snippet with the API key for your mParticle Web workspace.
This snippet pre-populates method stubs for much of the public SDK API, allowing immediate reference to these APIs as the SDK loads.
<script type="text/javascript">
//configure the SDK
window.mParticle = {
config: {
isDevelopmentMode: true,
identifyRequest: {
userIdentities: {
email: 'email@example.com',
customerid: '123456',
},
},
identityCallback: function(result) {
// Do something once an identity call has been made.
// For more information, see https://docs.mparticle.com/developers/sdk/web/idsync/#sdk-initialization-and-identify
console.log(result);
},
dataPlan: {
planId: 'my_plan_id',
planVersion: 2
}
},
};
//load the SDK
(function(e){window.mParticle=window.mParticle||{};window.mParticle.EventType={Unknown:0,Navigation:1,Location:2,Search:3,Transaction:4,UserContent:5,UserPreference:6,Social:7,Other:8,Media:9};window.mParticle.eCommerce={Cart:{}};window.mParticle.Identity={};window.mParticle.Rokt={};window.mParticle.config=window.mParticle.config||{};window.mParticle.config.rq=[];window.mParticle.config.snippetVersion=3;window.mParticle.ready=function(e){window.mParticle.config.rq.push(e)};var i=["endSession","logError","logBaseEvent","logEvent","logForm","logLink","logPageView","setSessionAttribute","setAppName","setAppVersion","setOptOut","setPosition","startNewSession","startTrackingLocation","stopTrackingLocation"];var t=["setCurrencyCode"];var n=["identify","login","logout","modify","search"];var o=["selectPlacements","hashAttributes","hashSha256","setExtensionData","use","getVersion","terminate","onShoppableAdsReady"];i.forEach(function(e){window.mParticle[e]=r(e)});t.forEach(function(e){window.mParticle.eCommerce[e]=r(e,"eCommerce")});n.forEach(function(e){window.mParticle.Identity[e]=r(e,"Identity")});o.forEach(function(e){window.mParticle.Rokt[e]=r(e,"Rokt")});function r(i,t){return function(){if(t){i=t+"."+i}var e=Array.prototype.slice.call(arguments);e.unshift(i);window.mParticle.config.rq.push(e)}}var a,c,s=window.mParticle.config,l=s.isDevelopmentMode?1:0,w="?env="+l,d=window.mParticle.config.dataPlan;if(d){a=d.planId;c=d.planVersion;if(a){if(c&&(c<1||c>1e3)){c=null}w+="&plan_id="+a+(c?"&plan_version="+c:"")}}var m=window.mParticle.config.versions;var f=[];if(m){Object.keys(m).forEach(function(e){f.push(e+"="+m[e])})}var p=document.createElement("script");p.type="text/javascript";p.charset="utf-8";p.async=true;p.src="https://jssdkcdns.mparticle.com/js/v3/"+e+"/mparticle.js"+w+"&"+f.join("&");var P=document.getElementsByTagName("script")[0];P.parentNode.insertBefore(p,P)})("REPLACE WITH API KEY");You can then log events, for example, as follows:
mParticle.logEvent('Play Movie', mParticle.EventType.Navigation, {
movie_length: '127 minutes',
rating: 'PG',
});In your root project directory, add the SDK to your package.json:
npm install @mparticle/web-sdk
// index.js
import mParticle from '@mparticle/web-sdk';
let mParticleConfig = {
isDevelopmentMode: true,
identifyRequest: {
userIdentities: {
email: 'email@example.com',
customerid: '123456',
},
},
identityCallback: myIdentityCallback,
dataPlan: {
planId: 'my_plan_id',
planVersion: 2,
},
};
mParticle.init('REPLACE WITH API KEY', mParticleConfig);You can then log events, for example, as follows:
mParticle.logEvent('Play Movie', mParticle.EventType.Navigation, {
movie_length: '127 minutes',
rating: 'PG',
});If you configure mParticle via a snippet tag, the Web SDK is able to automatically include, initialize, and delegate API calls to 3rd-party SDKs. Otherwise you will install them via npm. For more instructions on installing via npm, view the documentation.
If you would like to add your company as a new Javascript integration, reference the following integrations as examples:
- Amplitude
- Appboy
- BingAds
- Device Match
- Google Analytics
- Inspectlet
- Intercom
- Kahuna
- Kissmetrics
- Localytics
- Mixpanel
- Optimizely
- SimpleReach
See CONTRIBUTING.md.
The test script will run all tests using Karma and ChromeHeadless, and Firefox by default. To run tests using a different browser, use the command:
$ BROWSER=[browserBrand] npm run testBrowser
where browserBrand can be another browser such as Edge or IE.
This package comes with the NPM package pre-commit, which will run ESLint when you try to commit.
V2 and V3 release with separate workflows: staging-step-1.yml,
staging-step-2.yml and staging-step-3.yml for v2, and
v3-release-step-1.yml, v3-release-step-2.yml and v3-release-step-3.yml
for v3.
During the switch to the V3 files, staging-step-1.yml keeps its v3 track
and kit recovery. The first V3 release after the split still runs it from
v3-staging with track=v3, because v3-release-step-1.yml reaches main
only at that release's Step 3. If that release's kit publishing fails, resume
it with Staging Release - Step 1 from v3-staging (track=v3,
dryRun=false, resumeKitReleaseTag). The same release runs Steps 2 and 3
with Staging Release - Step 2 and Staging Release - Step 3 from main,
because v3-release-step-2.yml and v3-release-step-3.yml also reach main
only at its Step 3. Once a V3 release has run on
v3-release-step-1.yml, a follow-up removes the v3 track from
staging-step-1.yml. V2 runs the copies on staging and master, which this
split does not change.
The last V3 release cut by semantic-release, whose Step 3 brings main level
with v3-development, ends that path. Every later V3 release is cut from
main by Release Please, as the next section describes, and v3-development
is retired.
V3 pull requests merge to main. Release Please reads their Conventional
Commit titles and cuts each V3 release from main:
- V3 Release Please (
v3-release-please.yml) keeps one release pull request open onmain. It carries the next version, the changelog entry and the version of every kit. - On each push to that pull request, V3 Release Please - Commit Release
Bundles builds core and every kit at that version and commits
dist/andkits/**/distas the release machine user. The check V3 release bundles match version passes once the committed bundles match that build. No other pull request tomainmay changedist/orkits/**/dist(the check V3 bundles change only in release PRs). - Before merging the release pull request, check that it does not show "This
branch is out-of-date with the base branch". If it does, wait for Release
Please to rewrite it and for V3 release bundles match version to go
green again. Hold other merges to
mainfor a couple of minutes while you merge. Release Please publishes the GitHub release, creates thev3.X.Ytag on the merge commit, and dispatches V3 Release - Step 1 (v3-release-step-1.yml) on that tag withdryRun=false. - V3 Release - Step 1 checks that the tag is on
main, builds the distribution bundle, rebuilds core and every kit and compares them with the tag's bundles, and runs the test suites. Once the build, bundle check and tests pass, it publishes core and every kit to npmnext, movesv3-stagingforward to the tag commit, and uploads and stages the V3 candidate in S3. If the automatic dispatch from Release Please did not start Step 1 (or if Step 1 failed before packaging or staging started and needs to be started manually), run V3 Release - Step 1 manually from that tag (in Use workflow from, choose the tag, not a branch) withdryRun=false: it skips every package npm already holds with the same bytes. If a Step 1 run stops part-way after packaging or staging, use Re-run failed jobs on that original Step 1 run (see Recover an incomplete v3 kit publication). A Step 1 run from a tag runs only while the repository variableV3_RELEASE_PLEASE_ENABLEDistrue, and a run fromv3-stagingfails once it is. - Run Steps 2 and 3 from
mainas described below. Step 3 pushes only the three release-order branches, becausemainalready holds the release. Don't changeV3_RELEASE_PLEASE_ENABLEDwhile a Step 3 run or its S3 promote is in progress. If a promote skipped because the variable changed, runpromote-gaby hand.
main moves to the new version when the release pull request merges, and
ga serves it only after promote-ga. In that window main is ahead of
ga on every release. This is expected, and the gap closes at promote-ga.
Roll a release back with v3-shadow-promote: rollback for one channel, or
rollback-all for every channel in the selected pods. Rokt's internal V3 web
SDK delivery runbook holds the serving checks for each release.
Set the repository variable V3_DIST_GUARD_ENABLED to true once the first
Release Please release pull request's bundle commit shows as Verified on
GitHub. Until then, V3 bundles change only in release PRs passes with a
note. Then add it and V3 release bundles match version to the required
checks on main. When V3_DIST_GUARD_ENABLED is first set, or set again,
re-run V3 bundles change only in release PRs on every open pull request to
main. Each of them passed with a note while the variable was unset, and that
result stands until the check runs again.
- Run the last V3 release cut by semantic-release with the three steps below,
Step 1 from
v3-staging. Its Step 3 bringsmainlevel withv3-development, and with it V3 Release Please, which does nothing whileV3_RELEASE_PLEASE_ENABLEDis set tofalse. - Lock
v3-developmentwith its ruleset, and retarget its open pull requests tomain. From here on, V3 pull requests merge tomain. - Before
V3_RELEASE_PLEASE_ENABLEDis set, merge one small pull request tomainthat sets.release-please-manifest.jsonandCHANGELOG.mdto that release's version. The manifest reads that version. The changelog gains a# Changelogtitle, and each semantic-release# [3.X.0]heading becomes## [3.X.0]. Release Please adds each entry before the first##or###version heading, so without this its first entry would land below that release's. - Set
V3_RELEASE_PLEASE_ENABLEDtotrue. - Set
V3_DIST_GUARD_ENABLEDonce the first release pull request's bundle commit shows as Verified, as described above.
-
The release pull request merged, but no release or tag appeared. Re-run the failed V3 Release Please run. If it fails again, publish the release from your own machine with the same files, then run Step 1 from the new tag. The command pins release-please 17.6.0, the version that the workflow's pinned
googleapis/release-please-actionv5.0.0 locks. Change both pins together. ForGITHUB_TOKEN, create a fine-grained personal access token for this repository only, with a one-day expiry. Give it write access to Contents, Pull requests and Issues, and nothing else (GitHub adds read-only Metadata). Release Please labels the release pull request through the Issues API. Delete the token once the release is published.npx release-please@17.6.0 github-release --token "$GITHUB_TOKEN" \ --repo-url mParticle/mparticle-web-sdk --target-branch main \ --config-file release-please-config.json \ --manifest-file .release-please-manifest.json -
Abandon a release. Before the merge, close the release pull request. Release Please opens a new one on the next push to
main, with every unreleased change. To pause Release Please, setV3_RELEASE_PLEASE_ENABLEDtofalsefirst, then close the open release pull request. That pauses V3 releases. It does not bring back the semantic-release path (see Fall back to the semantic-release path). Don't use theautorelease: snoozelabel. Withalways-update, Release Please keeps force-updating a snoozed PR. After the merge, if a release must not ship, cancel the in-progress V3 Release - Step 1 run if it is still running, do not run Steps 2 or 3 for that tag, and do not re-dispatch Step 1 for it. Leave the tag and the GitHub release in place, never reuse the version, and merge the fix tomain. Release Please then cuts the next version, and Step 1 from that tag movesv3-stagingpast the abandoned one. This roll-forward is how to replace a bad release. -
Release a chosen version. Add the footer
Release-As: 3.X.Yto the commit message of a pull request merged tomain, for example by editing the squash commit message. The next release pull request then proposes 3.X.Y instead of the version the commit types give.
Fall back only when Release Please itself cannot cut releases. To replace one bad release, roll forward as Abandon a release describes.
Setting V3_RELEASE_PLEASE_ENABLED to false does not bring back the old
path on its own. Step 1 from v3-staging builds whatever v3-development
holds, and v3-development stops moving at the switch.
It is safe to fall back only when no release is part-way. Every tag Release Please cut has finished Step 3 or was abandoned, and no Step 1, 2 or 3 run is in progress. Then:
-
Set
V3_RELEASE_PLEASE_ENABLEDtofalsefirst, then close the open release pull request without merging it. -
Unset
V3_DIST_GUARD_ENABLED. Remove V3 bundles change only in release PRs and V3 release bundles match version from the required checks onmain. The old Step 3 pushes each release tomaindirectly, not through a pull request. -
Lift the ruleset that locks
v3-development. Then bringv3-developmentandv3-stagingup tomain. If either ancestor check fails, stop: that branch holds a commitmainlacks. Merge it intomainwith a pull request, then repeat this step. The push is not forced, so it only fast-forwards.git fetch origin main v3-development v3-staging git merge-base --is-ancestor origin/v3-development origin/main git merge-base --is-ancestor origin/v3-staging origin/main git push --atomic origin origin/main:refs/heads/v3-development \ origin/main:refs/heads/v3-staging
-
Point both Dependabot updates in
.github/dependabot.ymlback atv3-development, and merge V3 pull requests there again. From here on, only Step 3 movesmain. -
Release with the three steps below, Step 1 from
v3-staging. Step 1 and semantic-release take the newestv3.X.Ytag reachable fromv3-staging, a Release Please tag included, so the next version follows it.
Step 3 cannot push an older v3-development over a newer main. Without
Release Please it pushes all five branches, main included. Before the push
it checks that each one can fast-forward to the tag. If one cannot, it stops
with origin/main cannot fast-forward to v3.X.Y and pushes nothing. That
means a commit reached main outside Step 3. Merge main into
v3-development with a pull request, then run Step 1 again.
To return to Release Please, finish the last release's Step 3, so main and
v3-development are the same commit. Then merge one pull request to main
that sets .release-please-manifest.json and CHANGELOG.md to that release's
version, as step 3 of Switch to Release Please describes, and points
Dependabot back at main. Set V3_RELEASE_PLEASE_ENABLED to true, and merge
V3 pull requests to main again. Set V3_DIST_GUARD_ENABLED again as
described above.
In GitHub Actions, choose the version's branch from the Use workflow from dropdown and run its workflows in order:
- Step 1: Prepare CDN Pre-Release, Publish NPM: run
Staging Release - Step 1 (
staging-step-1.yml) fromstagingwithtrack=v2, or V3 Release - Step 1 (v3-release-step-1.yml) from the V3 release tag (see the section above; before Release Please, fromv3-staging). Fromstagingorv3-staging, this workflow builds and tests the version, creates and merges a generated release branch, runs semantic-release, and publishes the npm release. Before a new v3 release can advance, every existing kitnexttag must match the core SDK's currentnextversion. The one-time3.0.0bootstrap permits all kit tags to be absent so the first synchronized release can establish them. After building the target version, Step 1 also packs and registry-preflights all kit artifacts before publishing core. It then checks out the immutable release tag, waits up to five minutes for core to become visible on npm, publishes all packages inkits/publish-matrix.jsonconcurrently with a bounded worker pool, and runsauditRemotePackagesin strict mode at the end ofpublish-kits.js, reusing the tarballs it already packed so a missing or mismatched kit fails Publish V3 kits (publish-kits) beforeadvance-stagingmovesv3-staging(with no extranpm packand no extra workflow job). In V3 Release - Step 1, npm is then checked a second time by the release gate in Upload and stage V3 candidate described below:check-release-parity.tscompares every package'sdist.integritywith the candidate and reads npm again for up to 10 minutes before it fails the release. The gate does not read dist-tags:npm publish --tagsets them,assertDistTagWillNotMoveBackwardguards them before each publish,auditRemotePackagesverifies them at the end ofpublish-kits.js, and the next release's--preflight-tagsrefuses to start until every kit's tag matches core's. The standalone Audit V3 kits on npm entrypoint (publish-kits.js --audit) warns when npm has not confirmed a package yet and fails on a mismatched artifact or dist-tag (or fails on both when called with--strict), and stays callable for older Step 1 copies andstaging-step-1.yml's v3 track. The next Step 1 refuses to start until every kit'snextmatches core, so a kit that never appears blocks the next release rather than shipping unnoticed. A rerun skips an existing kit only when its artifact is identical.dryRun=truepreviews the merge and semantic-release result without creating a branch or publishing;dryRun=falsecreates/pushes the release branch and publishes. If core publishes but kit publication (or candidate upload/stage) cannot finish, recovery depends on the Step 1 mode: in tag mode (Release Please, dispatched fromv3.X.Y), use Re-run failed jobs on the original V3 Release - Step 1 run (which keeps the original packaged candidate and its${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}build ID; never start a fresh Step 1 run or use Re-run all jobs), or if kits andv3-stagingalready succeeded and only candidate upload or stage failed, dispatch V3 shadow release: upload candidate (v3-shadow-candidate.yml) onmainwithstep1_run_idset to the original Step 1 run ID,release_gate=true, andrelease_tagset to the release tag (v3.X.Y). In branch mode (dispatched fromv3-stagingbefore Release Please), rerun V3 Release - Step 1 fromv3-stagingwithdryRun=falseandresumeKitReleaseTagset to the exact Step 1 tag. Branch-mode recovery validates that immutable tag, resumes kits without republishing core, and runs the integrated strict npm audit at the end ofpublish-kits.jsso a missing or mismatched kit fails the recovery run. Because a branch-moderesumeKitReleaseTagrecovery run skips Perform Release, Package and Upload, once it finishes green dispatch V3 shadow release: upload candidate (v3-shadow-candidate.yml) onmainwithrelease_gate=trueandstep1_run_idset to the original Step 1 run. - Step 2: Publish SDK Release to Release Order Branch (optional): run
Staging Release - Step 2 (
staging-step-2.yml) frommasterfor v2, or V3 Release - Step 2 (v3-release-step-2.yml) frommainfor v3. Every run, dry runs included, rejects the other version's tag and a dispatch from any other branch. ForreleaseTag, enter the exact Git tag created by the successful Step 1 run (for example,v2.80.0orv3.0.1). Chooserelease-order-a,-b, or-casreleaseOrderBranch. For v3, that logical choice maps to the correspondingv3-release-order-*branch.dryRun=truevalidates the exact candidate and fast-forward without pushing;dryRun=falsepromotes it. - Step 3: Release to CDN and Synchronize Branches: run
Staging Release - Step 3 (
staging-step-3.yml) frommasterfor v2, or V3 Release - Step 3 (v3-release-step-3.yml) frommainfor v3, with the same rule as Step 2. ForreleaseTag, enter the same exact Git tag created by the successful Step 1 run. The workflow verifies that the tag matchespackage.json, resolves to the version's current staging head, and can fast-forward every destination. It then uses one atomic push, so either every ref updates or none does. For v2, and for v3 before Release Please, that push synchronizes the version's development branch, trunk (masterormain), and all three release-order branches. OnceV3_RELEASE_PLEASE_ENABLEDistrue, V3 Step 3 first checks that the tag is onmain, then pushes only the three release-order branches, becausemainalready holds the release andv3-developmentis retired.dryRun=trueperforms all validation without pushing.dryRun=falseperforms the atomic push and releases the candidate to those destinations.
Safe sequence: run Step 1 with dryRun=true, then Step 1 with dryRun=false;
copy its release tag; optionally preview and run Step 2 for each needed
release-order branch; finally run Step 3 with dryRun=true, then
dryRun=false.
V3 candidate packaging, upload, and staging: a real V3 Release - Step 1
(v3-release-step-1.yml, dryRun=false) runs Package V3 candidate
(shadow) after the release to package the release tag's committed bundles
into a v3-candidate-<run id>-<run attempt> artifact (kept for 7 days). Once
Publish V3 kits has also succeeded, it runs
Upload and stage V3 candidate, which dispatches V3 shadow
release: upload candidate (v3-shadow-candidate.yml) on main with
release_gate=true and waits up to 120 minutes (the child jobs' 110-minute
ceiling plus 10 minutes of queue time, inside a 130-minute job timeout) for it
to succeed. A failed read of the child run's status (a 5xx or rate-limit reply)
is retried until that deadline. If the job fails, times out or is cancelled
before the child run completes, it cancels the child run. A refused cancel (a
5xx or rate-limit reply) is retried with a doubling backoff (6 tries, 5 seconds
apart at first) until GitHub accepts it or the child run reads completed, first
by the wait step and then by the cleanup step. Release-gate dispatches for one
Step 1 run share one concurrency group (v3-shadow-candidate-gate-STEP1_RUN_ID),
so a re-run's child queues behind a leftover child instead of staging the same
build in parallel with it. A newer gate dispatch for the same Step 1 run takes
the group's single pending slot from an older pending one, which then fails its
own Step 1 wait. A manual dispatch with release_gate=false or a transition
workflow_run runs in another group, so it cannot displace a pending gate run.
If the dispatch request succeeds but its reply is lost or carries no
workflow_run_id, the job fails with no child run ID, so nothing cancels that
child. Before re-running Step 1, open the V3 shadow release: upload
candidate runs, find any run dispatched after the failed Step 1 run started,
and cancel it if it is still running. If it is missed, the shared concurrency
group still makes the re-run's child wait for it to finish.
Release-gate mode accepts both an in-progress v3-release-step-1.yml
parent run and one that has already
completed without being cancelled (so a maintainer can also dispatch
v3-shadow-candidate.yml manually with release_gate=true for repair after
Step 1 finishes), provided Perform Release and Package V3 candidate
(shadow) succeeded and one unexpired candidate artifact exists. Release-gate
mode also requires npm parity to pass: every package must be on npm with the
candidate's integrity. npm can take minutes to show a version it has
accepted, so while npm parity reads pending (a version npm does not show yet) or unavailable
(an npm view error or an unexpected reply), the candidate workflow reads npm
again with a doubling backoff (15 seconds at first, at most 2 minutes apart)
for up to 10 minutes, with a last read when the 10 minutes run out. A fail
reading (a published package with another integrity) fails the gate at once,
and a read stops at the first package that differs. A package still pending
or unavailable after the last read fails the gate instead of uploading. Each
npm view gets at most 30 seconds, and each read of every package at most 2
minutes. A package the read has no time left for reads unavailable. If sleep
fails between reads, the check fails instead of reading npm again at once. A
transition workflow_run, or a manual dispatch with release_gate=false,
reads npm once. The Check the candidate against the release job's
25-minute timeout covers the 10 minutes, a last read of at most 2 minutes and
its other checks.
A failure in packaging, candidate verification, S3
upload, or v3-staging pointer staging fails the Step 1 release. In
release-gate mode, V3_SHADOW_PODS must include all five production pods
(us1, us2, st1, eu1, au1); qa is optional (if qa is listed in
V3_SHADOW_PODS, it runs in the same matrix and blocks the release on failure;
if qa is omitted from V3_SHADOW_PODS, only the five
production pods block the release and qa can run separately). Stage moves each
pod's v3-staging pointer independently in parallel, so if one pod fails, the
other pods have already moved to the new candidate; re-running failed jobs on
Step 1 (within the 7-day artifact window) re-runs Upload and stage V3
candidate, dispatches the candidate workflow again, and repairs the remaining
pods so every pod converges (resumeKitReleaseTag skips packaging and upload
as before). During the transition before a V3 release's Step 3 brings these
workflow updates to main, the shared Staging Release - Step 1
(staging-step-1.yml, track=v3) still uses the V3_PACKAGE_CANDIDATE
repository variable and the workflow_run trigger on main, so
V3_PACKAGE_CANDIDATE stays true until that transition release finishes.
A real v3 Step 1 run can publish core and create the GitHub Release before all 33 kits finish. If the kit job fails:
- Do not start a newer release or run Step 2 or Step 3.
- Copy the exact release tag from the failed Step 1 run.
- Use the failed job and its npm kit publish summary to identify any missing or rejected kits. Correct their npm or trusted-publisher configuration.
- For a Release Please release (dispatched from a
v3.X.Ytag), use Re-run failed jobs on the original V3 Release - Step 1 run (which keeps the successful package job and its${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}build ID; never start a fresh Step 1 run or use Re-run all jobs), and skip the rest of this step. Otherwise, dispatch V3 Release - Step 1 fromv3-stagingwithdryRun=falseandresumeKitReleaseTagset to the failed run's exact tag. Ifmainhas nov3-release-step-1.ymlyet (the first V3 release after the split), dispatch Staging Release - Step 1 fromv3-stagingwithtrack=v3and the same two inputs instead. - Wait for recovery to publish any missing kits (existing byte-identical
packages are skipped) and for
publish-kits.jsto run its integrated strict npm audit to verify core and all 33 kits at that version onnextand fail on any missing or mismatched package. - For a Release Please release, Re-run failed jobs on the original Step 1
run re-runs
advance-stagingandupload-v3-candidateusing the original run's packaged candidate (or, ifv3-stagingalready moved and only candidate upload or stage failed, dispatch V3 shadow release: upload candidate (v3-shadow-candidate.yml) onmainwithstep1_run_idset to the original Step 1 run's ID,release_gate=true, andrelease_tagset to the release tagv3.X.Ywithin the candidate's 7-day retention window). Otherwise, if the failed run was V3 Release - Step 1 fromv3-staging, it did not upload or stage its candidate becauseresumeKitReleaseTagskips packaging and upload: dispatch V3 shadow release: upload candidate (v3-shadow-candidate.yml) onmainwithstep1_run_idset to the original failed Step 1 run's ID andrelease_gate=true, within the candidate's 7 days. - Continue to Step 2 or Step 3 only after the recovery run and the candidate upload are green.
In tag mode, v3-staging moves to the release tag before the S3 upload and
stage runs. If v3-staging moves and the S3 upload or stage then fails,
recover by using Re-run failed jobs on the original V3 Release - Step 1
run (which preserves the successful package job and its
${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT} build ID) or by dispatching V3
shadow release: upload candidate (v3-shadow-candidate.yml) on main with
step1_run_id set to the original Step 1 run's ID, release_gate=true, and
release_tag set to the release tag (v3.X.Y),
within the candidate's 7-day artifact retention window. Never start a fresh
Step 1 run or use Re-run all jobs for recovery after any pod has staged:
that packages a new ${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT} build ID, and
promote-v3-release.ts rejects a different build of the same version on
already-staged pods without --allow-rebuild. When release_tag is omitted on
a tag-origin run (for example, when re-running failed jobs on an earlier
release tag whose v3-release-step-1.yml predates release_tag),
shadow-release-trigger.ts reads the release tag from the Step 1 run's
head_branch, logs a warning that the caller predates release_tag, and
continues; the check fails only when release_tag is provided and differs from
head_branch. Any rollback of this change on main must keep the
release_tag input declaration on v3-shadow-candidate.yml so Step 1 runs
from newer tags that send inputs[release_tag] can still dispatch the workflow
without GitHub rejecting release_tag as an unexpected input.
If recovery reports that the tagged core version is missing from npm, stop the kit recovery. Semantic-release may have pushed the generated staging commit and tag before core publication failed:
- Wait for npm propagation and confirm whether the tagged core version exists.
- If core appears, rerun the kit recovery above with the same tag.
- If core is confirmed absent, use the controlled maintainer procedure to
restore
v3-stagingto the parent of the generated release commit and delete the automation-created orphan tag. - Rerun a normal Step 1 release with
resumeKitReleaseTagempty.
Do not delete or move the tag until npm absence is confirmed. An npm publish that times out locally can still succeed in the registry.
If core's next tag changes without a corresponding Step 1 Git tag, do not use
the bootstrap exception or guess a recovery tag. Stop releases and reconcile
the unexpected npm and Git state before continuing.
Each version's trunk owns its own copy of its release workflows: master for
v2 and main for v3. A change to one version's release steps does not need a
twin on the other trunk. Steps 2 and 3 run from the dispatching trunk, and the
rule above keeps each version on its own trunk's copy. GitHub executes Step 1
from the branch selected in the Use workflow from dropdown, so every
dryRun=false Step 1 run rejects the release unless its workflow on the
staging branch is identical to its trunk's copy: staging-step-1.yml on
staging to master's, and v3-release-step-1.yml on v3-staging to
main's. During the switch to the V3 files, a track=v3 run of
staging-step-1.yml from v3-staging must match main's copy instead. A V3
Step 1 run from a release tag requires the tag's commit to be on main
instead, so a later edit to the workflow on main does not block an earlier
tag.
npm trusted publishing names the workflow file that publishes each package:
staging-step-1.yml publishes v2 of @mparticle/web-sdk, and
v3-release-step-1.yml publishes v3 of @mparticle/web-sdk and every kit in
kits/publish-matrix.json. Until a V3 release has run on
v3-release-step-1.yml, each of those packages keeps staging-step-1.yml as a
trusted publisher too, so the first V3 release after the split can publish.
The mParticle Web SDK is available under the Apache License, Version 2.0. See the LICENSE file for more info.
This project is tested with BrowserStack