Skip to content

Commit 018a809

Browse files
committed
crate.settings: Add "Trusted Publishing" section
This section lists the configured Trusted Publishing configurations for this crate. Until we publicly ship this feature the section is hidden, unless the crate already has corresponding configurations configured.
1 parent 6dae308 commit 018a809

File tree

5 files changed

+164
-2
lines changed

5 files changed

+164
-2
lines changed

app/routes/crate/settings.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import AuthenticatedRoute from '../-authenticated-route';
55
export default class SettingsRoute extends AuthenticatedRoute {
66
@service router;
77
@service session;
8+
@service store;
89

910
async beforeModel(transition) {
1011
await super.beforeModel(...arguments);
@@ -20,9 +21,18 @@ export default class SettingsRoute extends AuthenticatedRoute {
2021
}
2122
}
2223

23-
setupController(controller) {
24-
super.setupController(...arguments);
24+
async model() {
2525
let crate = this.modelFor('crate');
26+
27+
let githubConfigs = await this.store.query('trustpub-github-config', { crate: crate.name });
28+
29+
return { crate, githubConfigs };
30+
}
31+
32+
setupController(controller, { crate, githubConfigs }) {
33+
super.setupController(...arguments);
34+
2635
controller.set('crate', crate);
36+
controller.set('githubConfigs', githubConfigs);
2737
}
2838
}

app/styles/crate/settings.module.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@
4343
}
4444
}
4545

46+
.trustpub {
47+
background-color: light-dark(white, #141413);
48+
border-radius: var(--space-3xs);
49+
box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321);
50+
51+
tbody > tr > td {
52+
border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321);
53+
}
54+
55+
th, td {
56+
text-align: left;
57+
padding: var(--space-s) var(--space-m);
58+
}
59+
60+
.details {
61+
font-size: 0.85em;
62+
line-height: 1.5;
63+
}
64+
}
65+
4666
.email-column {
4767
width: 25%;
4868
color: var(--main-color-light);

app/templates/crate/settings.hbs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,38 @@
5454
{{/each}}
5555
</div>
5656

57+
{{! The "Trusted Publishing" section is hidden for now until we make this feature publicly available. }}
58+
{{#if this.githubConfigs}}
59+
<h2>Trusted Publishing</h2>
60+
61+
<table local-class="trustpub" data-test-trusted-publishing>
62+
<thead>
63+
<tr>
64+
<th>Publisher</th>
65+
<th>Details</th>
66+
</tr>
67+
</thead>
68+
<tbody>
69+
{{#each this.githubConfigs as |config|}}
70+
<tr data-test-github-config={{config.id}}>
71+
<td>GitHub</td>
72+
<td local-class="details">
73+
<strong>Repository:</strong> {{config.repository_owner}}/{{config.repository_name}}<br>
74+
<strong>Workflow:</strong> {{config.workflow_filename}}<br>
75+
{{#if config.environment}}
76+
<strong>Environment:</strong> {{config.environment}}
77+
{{/if}}
78+
</td>
79+
</tr>
80+
{{else}}
81+
<tr data-test-no-config>
82+
<td colspan="2">No trusted publishers configured for this crate.</td>
83+
</tr>
84+
{{/each}}
85+
</tbody>
86+
</table>
87+
{{/if}}
88+
5789
<h2>Danger Zone</h2>
5890

5991
<div>

e2e/routes/crate/settings.spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,59 @@ test.describe('Route | crate.settings', { tag: '@routes' }, () => {
4343

4444
await page.goto('/crates/foo/settings');
4545
await expect(page).toHaveURL('/crates/foo/settings');
46+
4647
await expect(page.locator('[data-test-owners]')).toBeVisible();
4748
await expect(page.locator('[data-test-add-owner-button]')).toBeVisible();
4849
await expect(page.locator(`[data-test-owner-user="${user.login}"]`)).toBeVisible();
4950
await expect(page.locator('[data-test-remove-owner-button]')).toBeVisible();
51+
52+
// Disabled for now, until we make this feature publicly available
53+
// await expect(page.locator('[data-test-trusted-publishing]')).toBeVisible();
54+
// await expect(page.locator('[data-test-no-config]')).toBeVisible();
55+
// await expect(page.locator('[data-test-github-config]')).not.toBeVisible();
56+
await expect(page.locator('[data-test-trusted-publishing]')).not.toBeVisible();
57+
5058
await expect(page.locator('[data-test-delete-button]')).toBeVisible();
5159
});
60+
61+
test.describe('Trusted Publishing', () => {
62+
test('happy path', async ({ msw, page, percy }) => {
63+
const { crate } = await prepare(msw);
64+
65+
// Create two GitHub configs for the crate
66+
msw.db.trustpubGithubConfig.create({
67+
crate,
68+
repository_owner: 'rust-lang',
69+
repository_name: 'crates.io',
70+
workflow_filename: 'ci.yml',
71+
});
72+
73+
msw.db.trustpubGithubConfig.create({
74+
crate,
75+
repository_owner: 'johndoe',
76+
repository_name: 'crates.io',
77+
workflow_filename: 'release.yml',
78+
environment: 'release',
79+
});
80+
81+
await page.goto('/crates/foo/settings');
82+
await expect(page).toHaveURL('/crates/foo/settings');
83+
84+
await percy.snapshot();
85+
86+
await expect(page.locator('[data-test-trusted-publishing]')).toBeVisible();
87+
await expect(page.locator('[data-test-github-config]')).toHaveCount(2);
88+
await expect(page.locator('[data-test-github-config="1"] td:nth-child(1)')).toHaveText('GitHub');
89+
let details = page.locator('[data-test-github-config="1"] td:nth-child(2)');
90+
await expect(details).toContainText('Repository: rust-lang/crates.io');
91+
await expect(details).toContainText('Workflow: ci.yml');
92+
await expect(details).not.toContainText('Environment');
93+
await expect(page.locator('[data-test-github-config="2"] td:nth-child(1)')).toHaveText('GitHub');
94+
details = page.locator('[data-test-github-config="2"] td:nth-child(2)');
95+
await expect(details).toContainText('Repository: johndoe/crates.io');
96+
await expect(details).toContainText('Workflow: release.yml');
97+
await expect(details).toContainText('Environment: release');
98+
await expect(page.locator('[data-test-no-config]')).not.toBeVisible();
99+
});
100+
});
52101
});

tests/routes/crate/settings-test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { currentURL } from '@ember/test-helpers';
22
import { module, test } from 'qunit';
33

4+
import percySnapshot from '@percy/ember';
5+
46
import { setupApplicationTest } from 'crates-io/tests/helpers';
57

68
import { visit } from '../../helpers/visit-ignoring-abort';
@@ -46,10 +48,59 @@ module('Route | crate.settings', hooks => {
4648

4749
await visit(`/crates/${crate.name}/settings`);
4850
assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`);
51+
4952
assert.dom('[data-test-add-owner-button]').exists();
5053
assert.dom('[data-test-owners]').exists();
5154
assert.dom(`[data-test-owner-user="${user.login}"]`).exists();
5255
assert.dom('[data-test-remove-owner-button]').exists();
56+
57+
// Disabled for now, until we make this feature publicly available
58+
// assert.dom('[data-test-trusted-publishing]').exists();
59+
// assert.dom('[data-test-no-config]').exists();
60+
// assert.dom('[data-test-github-config]').doesNotExist();
61+
assert.dom('[data-test-trusted-publishing]').doesNotExist();
62+
5363
assert.dom('[data-test-delete-button]').exists();
5464
});
65+
66+
module('Trusted Publishing', function () {
67+
test('happy path', async function (assert) {
68+
const { crate, user } = prepare(this);
69+
this.authenticateAs(user);
70+
71+
// Create two GitHub configs for the crate
72+
this.db.trustpubGithubConfig.create({
73+
crate,
74+
repository_owner: 'rust-lang',
75+
repository_name: 'crates.io',
76+
workflow_filename: 'ci.yml',
77+
});
78+
79+
this.db.trustpubGithubConfig.create({
80+
crate,
81+
repository_owner: 'johndoe',
82+
repository_name: 'crates.io',
83+
workflow_filename: 'release.yml',
84+
environment: 'release',
85+
});
86+
87+
await visit(`/crates/${crate.name}/settings`);
88+
assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`);
89+
90+
await percySnapshot(assert);
91+
92+
// Check that the GitHub config is displayed
93+
assert.dom('[data-test-trusted-publishing]').exists();
94+
assert.dom('[data-test-github-config]').exists({ count: 2 });
95+
assert.dom('[data-test-github-config="1"] td:nth-child(1)').hasText('GitHub');
96+
assert.dom('[data-test-github-config="1"] td:nth-child(2)').includesText('Repository: rust-lang/crates.io');
97+
assert.dom('[data-test-github-config="1"] td:nth-child(2)').includesText('Workflow: ci.yml');
98+
assert.dom('[data-test-github-config="1"] td:nth-child(2)').doesNotIncludeText('Environment');
99+
assert.dom('[data-test-github-config="2"] td:nth-child(1)').hasText('GitHub');
100+
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Repository: johndoe/crates.io');
101+
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Workflow: release.yml');
102+
assert.dom('[data-test-github-config="2"] td:nth-child(2)').includesText('Environment: release');
103+
assert.dom('[data-test-no-config]').doesNotExist();
104+
});
105+
});
55106
});

0 commit comments

Comments
 (0)