Beta build is blocked by the sample email templates
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Needs clarification
- Activity status
- Quiet
- Domain
- build-system, release
Research direction
Read cumulusci.yml and sfdx-project.json alongside the ancestry documentation; start by reviewing the package configuration and the evidence from PRs #215 and #216. Confirm the selected package strategy and separate source changes from Dev Hub and subscriber migration work. Done means the team has chosen a direction and the required build and migration steps are tracked.
Written by the indexing model from the issue text.
Description
Summary
The beta build is currently broken. The cause is the three sample email
templates. Testing shows that no arrangement of these templates inside the
current package can both build and install. The suggested fix is to start a new
package in the same namespace, drop the sample templates from the managed
package, and deliver them a different way. Pilot users would reinstall once. This
note asks the team to choose a direction.
What is broken
- When the templates are missing from the code, the build fails. Salesforce
saysEmailTemplate can't be removed. - When the templates are present, the build passes but the install fails. The
install says the templateis located in both the package and the unfiled-public folder.
Once a managed package ships an email template, it cannot be removed later. It
also cannot live in the shared "unfiled public" folder, which is where the
released version keeps them.
Why all four arrangements fail
The current package has four possible template arrangements. All four were
tested:
| Templates in the code | Build | Install |
|---|---|---|
| None | Fails (can't remove) | n/a |
| In the shared public folder | Passes | Fails (collision) |
| In a named folder only | Fails (can't remove the public ones) | n/a |
| Both | Passes | Fails (collision) |
The current package cannot produce a version that both builds and installs.
Pilot users who already installed keep working, but we cannot ship a new version
to them or to anyone new.
What this means for users
The app is still in pilot. It has not passed Security Review (issue #138), so it
is not on the AppExchange yet. The public still uses the old version 3 app. We do
not have an exact count of pilot installs. Now is the cheapest time to make this
change, before the public launch.
Options
| Option | Builds and installs? | Effect on pilot users | Main risk |
|---|---|---|---|
| Keep trying to fix the current package | No. Tested, does not work. | None | Stays broken |
| Change the test setup to skip the templates | No. Real installs still fail. | None | Green build that hides a broken install |
| New package, same namespace, templates delivered outside the package | Yes | Reinstall once, short link downtime | Reinstall must be run per org |
| Brand new package and new namespace | Yes | Reinstall once, old unsubscribe links break | Most rework, links break |
Recommendation
Start a new package in the same namespace. A new package means a new package id
and a fresh version history, with none of the shipped templates locked into it.
Take the three sample templates out of the managed package. Deliver them as
unpackaged metadata in a separate optional step during installation, so admins
can edit or remove them freely.
- A fresh package has no history to conflict with, so the build and install both
pass. This is the only tested path that produces a working install. - Keeping the same namespace means every field keeps its name. The unsubscribe
links already sent to people can keep working after the switch. - The templates were always samples. Delivering them outside the package keeps
this problem from coming back. Admins can change or delete them anytime.
What it costs pilot users:
- Each pilot org uninstalls the old version and installs the new one. There is no
in-place upgrade between two separate packages. - During the switch there is a short window where the unsubscribe links do not
work, because the old version is gone and the new one is not in yet. - We keep the opt-out records and the link values. Some system fields, like
original created dates and field history, reset. - Not tested: the unsubscribe web page is set up inside each org and is not part
of the package. If it does not survive the uninstall and reinstall, the links
break and the org admin must set the page up again.
Also valid: reuse the current package, but build the next version with no
ancestor so the build stops comparing against the released 0.3.0.2 and no
longer tries to remove the templates. This keeps the current package id. The
trade-off is that a version built with no ancestor cannot be upgraded to from the
released versions, and it leaves a broken upgrade history on that package id that
can fail later builds. A fresh package starts clean and avoids that. Same
one-time reinstall for pilot users either way. See the ancestry doc.
Suggested next step
The team chooses a direction: new package (recommended), reuse the current
package with no ancestor, or something else. If the team chooses the new package,
the work splits into two parts:
- Source change (a normal pull request, no Dev Hub access needed): rename the
package incumulusci.yml(project.package.name) and insfdx-project.json
(thepackagename and the stalepackageAliases), and add the three sample
templates back as unpackaged metadata for delivery at install time. - Dev Hub and subscriber-org actions (needs Dev Hub access, so RelEng
completes): promote the release and run the per-org migration.
Technical details and evidence
Note on terms: "new package" below means a new Package2 (0Ho...) in the same
namespace. Same namespace with a new package is a supported 2GP shape.
The block
- Package:
0Ho6g000000KzbvCAC, namespaceUnsubscribeLnk, Dev Hub
00D6g000007zf5wEAA(OSC-devhub). - Released chain is linear:
0.1.0.8 -> 0.2.0.6 -> 0.3.0.2. When
create_package_versionbuilds a new version, it compares the source against
the highest promoted version and flags anything present there but missing now
as a removed component.0.3.0.2(04tKf0000011MN6IAM) is the highest
promoted version and it carries the three templates inunfiled$public. So a
build with the templates absent diffs against0.3.0.2, sees them as removed,
and fails. - Setting
0.2.0.6(the last template-free release) as the ancestor does not
avoid this. A normal build must use the highest promoted version as its
ancestor; the CLI rejects an older ancestor unless you pass
--skip-ancestor-check. Skipping the check to build against0.2.0.6, or
building with no ancestor, is the reuse option in the recommendation: create
passes, but the upgrade path from the released versions breaks. EmailTemplateis not in the removable-component list for 2GP. The Dev Hub
RemoveManagedComponentsAllowedflag does not unlock it; that flag only covers
the listed types, and access still needs a Salesforce Partner Support case. See
the removable components list.- The baseline keeps the templates in
unfiled$public, not a named folder.
Proof: PR #215 build (run 31140511460) failed atcreate_package_versionand
listed the removed components asunfiled$public/Sample_Contact_Template_HTML,
unfiled$public/Sample_Lead_Template_HTML,
unfiled$public/Sample_Lead_Template_Plain_Text. - PR #216 build (run 31193777829) shipped both the named folder and the
unfiled$publiccopies. Package creation passed. Beta install failed with the
both-locations collision. - The collision is between the packaged
EmailTemplateand the org-owned
unfiled$publicEmailFolder, not a pre-existing same-named template. Every
org has anunfiled$publicEmailFolder, so a packagedEmailTemplatethat
targets it collides on every install. Test: installed beta0.4.0.6
(04tKf000000kjbCIAQ) into a fresh scratch org with zero pre-existing Sample
templates and nothing in unfiled-public. Install failed with
EmailTemplate Sample Lead Template file is located in both the package you tried to install, and in either the unfiled-public folder or a user folder. A
2GP package cannot deliver anEmailTemplateintounfiled$public.
The new package is feasible with current tooling
- Two 2GP packages can share one namespace in the same Dev Hub. See the
1GP vs 2GP comparison. - CumulusCI's
create_package_versionresolves the package by name and namespace
fromcumulusci.yml(project.package.name+project.package.namespace),
not by an id insfdx-project.json. If noPackage2matches, it creates one
using theDEV_HUB_AUTH_URLcredentials. So renamingproject.package.name
makes the next beta build stand up the new package unattended, provided the CI
identity has the "Create and Update Second-Generation Packages" permission it
already uses to build versions today. If it lacks package-create rights,
someone with Dev Hub access runssf package createonce by hand. - No GitHub workflow file needs a change.
beta.yml,prod.yml, and
feature.ymlcall the sharedstandard-workflowsworkflows and never pass a
package id.DEV_HUB_AUTH_URLdoes not change, because both packages live in
the same Dev Hub. - Manual Dev Hub equivalent, run by someone with Dev Hub access:
sf package create --name "<new-name>" --package-type Managed --path force-app --target-dev-hub OSC-devhub, thensf package version create, then
sf package version promote.
Who runs each step
- Source edits (rename package in
cumulusci.yml+sfdx-project.json, add the
templates as unpackaged metadata): a pull request. Any contributor. No Dev Hub
access needed. - New
Package2create: automatic on the first beta build via CI, or a one-time
sf package createby someone with Dev Hub access if CI lacks the permission. - CI beta build: unattended, on merge to
main. - Version promote (release): needs Dev Hub access. Deliberate and irreversible.
- Subscriber migration: hand-held per pilot org, needs subscriber-org admin
access. There is no License Management App, so we cannot list installs
automatically. Each org needs direct outreach and a maintenance window.
Migration mechanics and limits
- No overlap window. Same namespace plus same field API names means an org cannot
hold both packages at once, so the sequence is: export data, uninstall old,
install new, re-import. Two package versions can upgrade in place only if they
share an ancestry path, which two separate packages never do. See the
upgrade/ancestry doc. - The uninstall and install steps are manual admin actions (Setup UI or
sf package uninstall/install). Only the data export and re-import can be
scripted. How to run those is the team's choice, based on how many pilot orgs
there are and the owner's bandwidth:- Automate as a CumulusCI flow:
extract_datasetbefore uninstall,
load_datasetafter install, matching on the external id. Repeatable per org. - Wrap it as a MetaDeploy plan for a guided, admin-run migration.
- For a few orgs, run the export and re-import by hand with Data Loader instead
of automating.
- Automate as a CumulusCI flow:
- Data surface:
Unsubscribe__crecords (opt-out data, must be preserved),
Contact.Public_Id__c(unique external id, backs live unsubscribe URLs, must
be preserved),Contact.Part1_Unsubscribe_Link__c(flow-populated), and the
Leadequivalents.Unsubscribe_Link_Setup__cis a custom setting
(re-enterable). Two formula fields carry no stored data. - Preserve
Public_Id__cby upsert on the external id field
(CumulusCIload_datasetor Data Loader), not plain insert. Lost on uninstall
and not restorable: original record ids, created/modified dates, field history. - Largest untested risk: the unsubscribe URL routes through an
Experience/Digital Experience site that each subscriber sets up. It is not a
package component. Whether its page references survive an uninstall then
reinstall is not confirmed. Confirm this in a test org before committing pilot
users.
- Dominant language
- Apex
- Stars
- 9
- Forks
- 22
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 3
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from SFDO-Community/UnsubscribeLink
-
Unsubscribe Link Quick fails on Next: ErrorRecipient is not an input on Unsubscribe ContactsPossibly taken @RubenHalman claimed this 14 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
SFDO-Community/UnsubscribeLink#238 ·
Maintainers usually reply within 1 day
-
Unsuscribe Errors Report is FailingPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SFDO-Community/UnsubscribeLink#236 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
SFDO-Community/UnsubscribeLink#212 · 1 comment ·
Maintainers usually reply within 1 day
-
Grant Email Opt Out access on install without cloning the permission setPossibly taken @RubenHalman claimed this 13 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 48/100
SFDO-Community/UnsubscribeLink#244 · 4 comments ·
Maintainers usually reply within 1 day
-
Risks involved with allowing users to Unsubscribe others by entering an email addressPossibly taken @RubenHalman claimed this 13 days ago. Open
Difficulty 5/5 Over a week Newbie friendliness 15/100
SFDO-Community/UnsubscribeLink#241 · 1 comment ·
Maintainers usually reply within 1 day
All issues in SFDO-Community/UnsubscribeLink
Similar issues
-
Run the dependency drift checkPossibly taken @spaceninja claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 72/100
cloudfour/lighthouse-parade#449 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
PostHog/posthog-js#5524 ·
Maintainers usually reply within 2 days
-
Remove unused dependenciesPossibly taken @alastair-smith claimed this today. Openchore other
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
alastair-smith/card-games#384 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
kivy/python-for-android#3405 · 1 reaction ·
Maintainers usually reply within 1 day
-
package-update
Difficulty 1/5 Under an hour Newbie friendliness 62/100
Maintainers usually reply within 1 day