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
11 changes: 11 additions & 0 deletions .github/workflows/ci-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,22 @@ concurrency:
group: ci-release-${{ github.ref_name }}
cancel-in-progress: false

# Workflow-level permissions set the ceiling for the reusable ci.yml.
# id-token is never in the default token, so it must be granted explicitly
# here — otherwise the ci: job's `permissions:` block exceeds the caller
# workflow's permissions and GitHub rejects the run with startup_failure.
permissions:
actions: read
contents: write
packages: write
id-token: write

jobs:
ci:
uses: ./.github/workflows/ci.yml
secrets: inherit
permissions:
actions: read
contents: write
packages: write
id-token: write
148 changes: 0 additions & 148 deletions .github/workflows/cleanup-stripe-test-accounts.yml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ const features: Feature[] = [{
title: 'Drip Sequences',
description: 'Enable welcome email drip sequences',
flag: 'dripSequences'
}, {
title: 'Welcome Emails Design Customization',
description: 'Enable design customization options for welcome emails',
flag: 'welcomeEmailsDesignCustomization'
}, {
title: 'Picture Element',
description: 'Use the HTML picture element to serve modern image formats (AVIF, WebP) with automatic fallbacks',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, {useEffect, useRef} from 'react';
import TopLevelGroup from '../../top-level-group';
import WelcomeEmailCustomizeModal from './member-emails/welcome-email-customize-modal';
import WelcomeEmailModal from './member-emails/welcome-email-modal';
import useFeatureFlag from '../../../hooks/use-feature-flag';
import useQueryParams from '../../../hooks/use-query-params';
import {APIError} from '@tryghost/admin-x-framework/errors';
import {Button, ConfirmationModal, Icon, Table, TableRow, Toggle, showToast, withErrorBoundary} from '@tryghost/admin-x-design-system';
Expand Down Expand Up @@ -133,7 +132,6 @@ const MemberEmailsTable: React.FC<{
};

const MemberEmails: React.FC<{ keywords: string[] }> = ({keywords}) => {
const hasDesignCustomization = useFeatureFlag('welcomeEmailsDesignCustomization');
const {settings, config} = useGlobalData();
const [siteTitle] = getSettingValues<string>(settings, ['title']);
const verifyEmailToken = useQueryParams().getParam('verifyEmail');
Expand Down Expand Up @@ -274,19 +272,18 @@ const MemberEmails: React.FC<{ keywords: string[] }> = ({keywords}) => {
// Get email to display (existing or default for preview)
const freeEmailForDisplay = freeWelcomeEmail || getDefaultWelcomeEmailRecord('free', siteTitle);
const paidEmailForDisplay = paidWelcomeEmail || getDefaultWelcomeEmailRecord('paid', siteTitle);
const customizeButton = hasDesignCustomization ? (
<Button
className='mt-[-5px]'
color='clear'
label='Customize'
size='sm'
onClick={() => NiceModal.show(WelcomeEmailCustomizeModal)}
/>
) : null;

return (
<TopLevelGroup
customButtons={customizeButton}
customButtons={(
<Button
className='mt-[-5px]'
color='clear'
label='Customize'
size='sm'
onClick={() => NiceModal.show(WelcomeEmailCustomizeModal)}
/>
)}
description="Create and manage automated emails for your members"
keywords={keywords}
navid='memberemails'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,12 @@ const configWithTenorEnabled = {
}
};

const configWithWelcomeEmailCustomization = {
const managedEmailConfigWithoutSendingDomain = {
...responseFixtures.config,
config: {
...responseFixtures.config.config,
labs: {
...responseFixtures.config.config.labs,
welcomeEmailsDesignCustomization: true
}
}
};

const managedEmailConfigWithoutSendingDomain = {
...configWithWelcomeEmailCustomization,
config: {
...configWithWelcomeEmailCustomization.config,
hostSettings: {
...configWithWelcomeEmailCustomization.config.hostSettings,
...responseFixtures.config.config.hostSettings,
managedEmail: {
enabled: true
}
Expand Down Expand Up @@ -656,7 +645,7 @@ test.describe('Member emails settings', async () => {
...globalDataRequests,
browseSettings: {...globalDataRequests.browseSettings, response: settingsWithPublicationIcon},
...newslettersRequest,
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture},
editAutomatedEmailDesign: {method: 'PUT', path: '/automated_emails/design/', response: automatedEmailDesignFixture},
Expand Down Expand Up @@ -699,7 +688,7 @@ test.describe('Member emails settings', async () => {
await mockApi({page, requests: {
...globalDataRequests,
...newslettersRequest,
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture}
}});
Expand All @@ -722,7 +711,7 @@ test.describe('Member emails settings', async () => {
await mockApi({page, requests: {
...globalDataRequests,
...newslettersRequest,
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture}
}});
Expand Down Expand Up @@ -763,7 +752,7 @@ test.describe('Member emails settings', async () => {
await mockApi({page, requests: {
...globalDataRequests,
browseNewslettersLimit: {method: 'GET', path: '/newsletters/?filter=status%3Aactive&limit=1', response: newsletterReplyToNewsletterResponse},
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture}
}});
Expand Down Expand Up @@ -799,7 +788,7 @@ test.describe('Member emails settings', async () => {
await mockApi({page, requests: {
...globalDataRequests,
browseNewslettersLimit: {method: 'GET', path: '/newsletters/?filter=status%3Aactive&limit=1', response: newsletterCustomReplyToResponse},
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture}
}});
Expand Down Expand Up @@ -860,7 +849,7 @@ test.describe('Member emails settings', async () => {
const {lastApiRequests} = await mockApi({page, requests: {
...globalDataRequests,
...newslettersRequest,
browseConfig: {method: 'GET', path: '/config/', response: configWithWelcomeEmailCustomization},
browseConfig: {method: 'GET', path: '/config/', response: responseFixtures.config},
browseAutomatedEmails: {method: 'GET', path: '/automated_emails/', response: automatedEmailsFixture},
readAutomatedEmailDesign: {method: 'GET', path: '/automated_emails/design/', response: automatedEmailDesignFixture},
editAutomatedEmailDesign: {method: 'PUT', path: '/automated_emails/design/', response: automatedEmailDesignFixture},
Expand Down
16 changes: 2 additions & 14 deletions e2e/tests/admin/settings/member-welcome-emails.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,8 @@ test.describe('Ghost Admin - Member Welcome Emails', () => {
});
});

test.describe('Ghost Admin - Welcome Email Customize Button - flag enabled', () => {
test.use({labs: {welcomeEmailsDesignCustomization: true}});

test('customize button opens modal when labs flag is enabled', async ({page}) => {
test.describe('Ghost Admin - Welcome Email Customize Button', () => {
test('customize button opens modal', async ({page}) => {
const welcomeEmailsSection = new MemberWelcomeEmailsSection(page);

await welcomeEmailsSection.goto();
Expand Down Expand Up @@ -375,16 +373,6 @@ test.describe('Ghost Admin - Welcome Email Customize Button - flag enabled', ()
});
});

test.describe('Ghost Admin - Welcome Email Customize Button - flag disabled', () => {
test('customize button is hidden when labs flag is disabled', async ({page}) => {
const welcomeEmailsSection = new MemberWelcomeEmailsSection(page);

await welcomeEmailsSection.goto();

await expect(welcomeEmailsSection.customizeButton).toBeHidden();
});
});

test.describe('Ghost Admin - Paid Member Welcome Emails', () => {
test.use({stripeEnabled: true});

Expand Down
2 changes: 1 addition & 1 deletion ghost/admin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ghost-admin",
"version": "6.32.0-rc.0",
"version": "6.33.0-rc.0",
"description": "Ember.js admin client for Ghost",
"author": "Ghost Foundation",
"homepage": "http://ghost.org",
Expand Down
2 changes: 1 addition & 1 deletion ghost/core/content/themes/casper
Submodule casper updated 2 files
+1 −1 gulpfile.js
+3 −2 package.json
2 changes: 1 addition & 1 deletion ghost/core/content/themes/source
25 changes: 16 additions & 9 deletions ghost/core/core/boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ async function initServices() {
const indexnow = require('./server/services/indexnow');
const slack = require('./server/services/slack');
const webhooks = require('./server/services/webhooks');
const scheduling = require('./server/adapters/scheduling');
const postScheduling = require('./server/services/post-scheduling');
const comments = require('./server/services/comments');
const staffService = require('./server/services/staff');
const memberAttribution = require('./server/services/member-attribution');
Expand All @@ -340,14 +340,19 @@ async function initServices() {
const statsService = require('./server/services/stats');
const explorePingService = require('./server/services/explore-ping');

const {
createAdapter: createSchedulerAdapter,
getSchedulerIntegration
} = require('./server/adapters/scheduling/utils');
const urlUtils = require('./shared/url-utils');

// NOTE: Members service depends on these
// so they are initialized before it.
await stripe.init();

// NOTE: newsletter service and email service depend on email address service
await emailAddressService.init(),
// Initialize things that other services depend on first.
const schedulerAdapter = createSchedulerAdapter();
const [schedulerIntegration] = await Promise.all([
getSchedulerIntegration(),
stripe.init(),
emailAddressService.init()
]);

await Promise.all([
identityTokens.init(),
Expand All @@ -366,8 +371,10 @@ async function initServices() {
emailService.init(),
emailAnalytics.init(),
webhooks.listen(),
scheduling.init({
apiUrl: urlUtils.urlFor('api', {type: 'admin'}, true)
postScheduling.init({
apiUrl: urlUtils.urlFor('api', {type: 'admin'}, true),
adapter: schedulerAdapter,
integration: schedulerIntegration
}),
comments.init(),
linkTracking.init(),
Expand Down
Loading
Loading