Skip to content

Commit 4bb9eda

Browse files
authored
trustpub: Prefill repo owner and name for crates with GitHub repo URLs (#11497)
When the user visits the form to create a new Trusted Publishing configuration, we look at the `repository` field of the crate, and if it is a GitHub URL (e.g. https://github.com/rust-lang/crates.io) we extract the repository owner and name from the URL and prefill the input fields accordingly. This should make the configuration creation a slightly more enjoyable experience.
1 parent 27097be commit 4bb9eda

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

app/routes/crate/settings/new-trusted-publisher.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,27 @@ export default class NewTrustedPublisherRoute extends Route {
55
let crate = this.modelFor('crate');
66
return { crate };
77
}
8+
9+
setupController(controller, model) {
10+
super.setupController(controller, model);
11+
12+
controller.repositoryOwner = '';
13+
controller.repositoryName = '';
14+
controller.workflowFilename = '';
15+
controller.environment = '';
16+
17+
let repository = model.crate.repository;
18+
if (repository && repository.startsWith('https://github.com/')) {
19+
try {
20+
let url = new URL(repository);
21+
let pathParts = url.pathname.slice(1).split('/');
22+
if (pathParts.length >= 2) {
23+
controller.repositoryOwner = pathParts[0];
24+
controller.repositoryName = pathParts[1].replace(/.git$/, '');
25+
}
26+
} catch {
27+
// ignore malformed URLs
28+
}
29+
}
30+
}
831
}

e2e/routes/crate/settings/new-trusted-publisher.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,67 @@ test.describe('Route | crate.settings.new-trusted-publisher', { tag: '@routes' }
182182
// Check that we're redirected back to the crate settings page
183183
await expect(page).toHaveURL(`/crates/${crate.name}/settings`);
184184
});
185+
186+
test.describe('prefill', () => {
187+
const testCases = [
188+
{
189+
name: 'simple https',
190+
url: 'https://github.com/rust-lang/crates.io',
191+
owner: 'rust-lang',
192+
repo: 'crates.io',
193+
},
194+
{
195+
name: 'with .git suffix',
196+
url: 'https://github.com/rust-lang/crates.io.git',
197+
owner: 'rust-lang',
198+
repo: 'crates.io',
199+
},
200+
{
201+
name: 'with extra path segments',
202+
url: 'https://github.com/Byron/google-apis-rs/tree/main/gen/privateca1',
203+
owner: 'Byron',
204+
repo: 'google-apis-rs',
205+
},
206+
{
207+
name: 'non-github url',
208+
url: 'https://gitlab.com/rust-lang/crates.io',
209+
owner: '',
210+
repo: '',
211+
},
212+
{
213+
name: 'not a url',
214+
url: 'not a url',
215+
owner: '',
216+
repo: '',
217+
},
218+
{
219+
name: 'empty string',
220+
url: '',
221+
owner: '',
222+
repo: '',
223+
},
224+
{
225+
name: 'null',
226+
url: null,
227+
owner: '',
228+
repo: '',
229+
},
230+
];
231+
232+
for (const { name, url, owner, repo } of testCases) {
233+
test(name, async ({ msw, page }) => {
234+
let { crate } = await prepare(msw);
235+
236+
msw.db.crate.update({
237+
where: { id: { equals: crate.id } },
238+
data: { repository: url },
239+
});
240+
241+
await page.goto(`/crates/${crate.name}/settings/new-trusted-publisher`);
242+
243+
await expect(page.locator('[data-test-repository-owner]')).toHaveValue(owner);
244+
await expect(page.locator('[data-test-repository-name]')).toHaveValue(repo);
245+
});
246+
}
247+
});
185248
});

tests/routes/crate/settings/new-trusted-publisher-test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,66 @@ module('Route | crate.settings.new-trusted-publisher', hooks => {
190190
// Check that we're redirected back to the crate settings page
191191
assert.strictEqual(currentURL(), `/crates/${crate.name}/settings`);
192192
});
193+
194+
module('prefill', function () {
195+
let testCases = [
196+
{
197+
name: 'simple https',
198+
url: 'https://github.com/rust-lang/crates.io',
199+
owner: 'rust-lang',
200+
repo: 'crates.io',
201+
},
202+
{
203+
name: 'with .git suffix',
204+
url: 'https://github.com/rust-lang/crates.io.git',
205+
owner: 'rust-lang',
206+
repo: 'crates.io',
207+
},
208+
{
209+
name: 'with extra path segments',
210+
url: 'https://github.com/Byron/google-apis-rs/tree/main/gen/privateca1',
211+
owner: 'Byron',
212+
repo: 'google-apis-rs',
213+
},
214+
{
215+
name: 'non-github url',
216+
url: 'https://gitlab.com/rust-lang/crates.io',
217+
owner: '',
218+
repo: '',
219+
},
220+
{
221+
name: 'not a url',
222+
url: 'not a url',
223+
owner: '',
224+
repo: '',
225+
},
226+
{
227+
name: 'empty string',
228+
url: '',
229+
owner: '',
230+
repo: '',
231+
},
232+
{
233+
name: 'null',
234+
url: null,
235+
owner: '',
236+
repo: '',
237+
},
238+
];
239+
240+
for (let { name, url, owner, repo } of testCases) {
241+
test(name, async function (assert) {
242+
let { crate } = prepare(this);
243+
this.db.crate.update({
244+
where: { id: { equals: crate.id } },
245+
data: { repository: url },
246+
});
247+
248+
await visit(`/crates/${crate.name}/settings/new-trusted-publisher`);
249+
250+
assert.dom('[data-test-repository-owner]').hasValue(owner);
251+
assert.dom('[data-test-repository-name]').hasValue(repo);
252+
});
253+
}
254+
});
193255
});

0 commit comments

Comments
 (0)