Merge 7f66fd81f417486a4cb39d695350c9765d8d150a into 6135dd51e565e014733437cd74457f6dfef45a53
3 files · +27 -4
M internal/app/ci_permissions_test.go +25 -2
| @@ -239,13 +239,36 @@ func TestJobTokenWithContentsWritePushesButNotWorkflows(t *testing.T) { | |||
| 239 | 239 | // None of the pushes of the job token started a run; a push of the owner | |
| 240 | 240 | // does, and queues after them. | |
| 241 | 241 | c.push("sentinel", map[string]string{"s.txt": "s"}, "") | |
| 242 | - | c.waitFor("the owner's runs", func() bool { return len(c.runs()) >= runsBefore+4 }) | |
| 242 | + | // rworkflow carries both p.yml and moved.yml, each on push and create. | |
| 243 | + | // sentinel branches from ok (p.yml only), so adds two more runs. Wait for | |
| 244 | + | // its create run: planning is queued, and a total alone can be reached | |
| 245 | + | // before the owner's pushes have finished being planned. | |
| 246 | + | c.waitFor("the sentinel's create run", func() bool { | |
| 247 | + | for _, r := range c.runs() { | |
| 248 | + | if r.GetRef() == "refs/heads/sentinel" && r.GetEvent() == "create" { | |
| 249 | + | return true | |
| 250 | + | } | |
| 251 | + | } | |
| 252 | + | return false | |
| 253 | + | }) | |
| 254 | + | var ownerRuns []string | |
| 243 | 255 | for _, r := range c.runs() { | |
| 256 | + | if r.GetRef() == "refs/heads/rworkflow" || r.GetRef() == "refs/heads/sentinel" { | |
| 257 | + | ownerRuns = append(ownerRuns, r.GetRef()+" "+r.GetWorkflowPath()+" "+r.GetEvent()) | |
| 258 | + | } | |
| 244 | 259 | assert.NotEqual(t, "refs/heads/orphan", r.GetRef(), "no run for a job token's push") | |
| 245 | 260 | assert.NotEqual(t, "refs/tags/v0", r.GetRef()) | |
| 246 | 261 | assert.NotEqual(t, "delete", r.GetEvent(), "no run for a job token's deletes") | |
| 247 | 262 | } | |
| 248 | - | assert.Len(t, c.runs(), runsBefore+4, "push and create of the owner's rworkflow and sentinel only") | |
| 263 | + | assert.ElementsMatch(t, []string{ | |
| 264 | + | "refs/heads/rworkflow .github/workflows/p.yml push", | |
| 265 | + | "refs/heads/rworkflow .github/workflows/p.yml create", | |
| 266 | + | "refs/heads/rworkflow .github/workflows/moved.yml push", | |
| 267 | + | "refs/heads/rworkflow .github/workflows/moved.yml create", | |
| 268 | + | "refs/heads/sentinel .github/workflows/p.yml push", | |
| 269 | + | "refs/heads/sentinel .github/workflows/p.yml create", | |
| 270 | + | }, ownerRuns) | |
| 271 | + | assert.Len(t, c.runs(), runsBefore+6, "only the owner's two workflows on rworkflow and one on sentinel, each on push and create") | |
| 249 | 272 | } | |
| 250 | 273 | ||
| 251 | 274 | func TestJobTokenCannotPushToAnotherRepository(t *testing.T) { | |
| @@ -239,13 +239,36 @@ func TestJobTokenWithContentsWritePushesButNotWorkflows(t *testing.T) { | |||||
| 239 | // None of the pushes of the job token started a run; a push of the owner | 239 | // None of the pushes of the job token started a run; a push of the owner | ||
| 240 | // does, and queues after them. | 240 | // does, and queues after them. | ||
| 241 | c.push("sentinel", map[string]string{"s.txt": "s"}, "") | 241 | c.push("sentinel", map[string]string{"s.txt": "s"}, "") | ||
| 242 | - | c.waitFor("the owner's runs", func() bool { return len(c.runs()) >= runsBefore+4 }) | 242 | + | // rworkflow carries both p.yml and moved.yml, each on push and create. |
| 243 | + | // sentinel branches from ok (p.yml only), so adds two more runs. Wait for | |||
| 244 | + | // its create run: planning is queued, and a total alone can be reached | |||
| 245 | + | // before the owner's pushes have finished being planned. | |||
| 246 | + | c.waitFor("the sentinel's create run", func() bool { | |||
| 247 | + | for _, r := range c.runs() { | |||
| 248 | + | if r.GetRef() == "refs/heads/sentinel" && r.GetEvent() == "create" { | |||
| 249 | + | return true | |||
| 250 | + | } | |||
| 251 | + | } | |||
| 252 | + | return false | |||
| 253 | + | }) | |||
| 254 | + | var ownerRuns []string | |||
| 243 | for _, r := range c.runs() { | 255 | for _, r := range c.runs() { | ||
| 256 | + | if r.GetRef() == "refs/heads/rworkflow" || r.GetRef() == "refs/heads/sentinel" { | |||
| 257 | + | ownerRuns = append(ownerRuns, r.GetRef()+" "+r.GetWorkflowPath()+" "+r.GetEvent()) | |||
| 258 | + | } | |||
| 244 | assert.NotEqual(t, "refs/heads/orphan", r.GetRef(), "no run for a job token's push") | 259 | assert.NotEqual(t, "refs/heads/orphan", r.GetRef(), "no run for a job token's push") | ||
| 245 | assert.NotEqual(t, "refs/tags/v0", r.GetRef()) | 260 | assert.NotEqual(t, "refs/tags/v0", r.GetRef()) | ||
| 246 | assert.NotEqual(t, "delete", r.GetEvent(), "no run for a job token's deletes") | 261 | assert.NotEqual(t, "delete", r.GetEvent(), "no run for a job token's deletes") | ||
| 247 | } | 262 | } | ||
| 248 | - | assert.Len(t, c.runs(), runsBefore+4, "push and create of the owner's rworkflow and sentinel only") | 263 | + | assert.ElementsMatch(t, []string{ |
| 264 | + | "refs/heads/rworkflow .github/workflows/p.yml push", | |||
| 265 | + | "refs/heads/rworkflow .github/workflows/p.yml create", | |||
| 266 | + | "refs/heads/rworkflow .github/workflows/moved.yml push", | |||
| 267 | + | "refs/heads/rworkflow .github/workflows/moved.yml create", | |||
| 268 | + | "refs/heads/sentinel .github/workflows/p.yml push", | |||
| 269 | + | "refs/heads/sentinel .github/workflows/p.yml create", | |||
| 270 | + | }, ownerRuns) | |||
| 271 | + | assert.Len(t, c.runs(), runsBefore+6, "only the owner's two workflows on rworkflow and one on sentinel, each on push and create") | |||
| 249 | } | 272 | } | ||
| 250 | 273 | ||||
| 251 | func TestJobTokenCannotPushToAnotherRepository(t *testing.T) { | 274 | func TestJobTokenCannotPushToAnotherRepository(t *testing.T) { | ||
M internal/app/testdata/web/blob-markdown.html +1 -1
| @@ -116,7 +116,7 @@ | |||
| 116 | 116 | <h1 id="md-guide">Guide</h1> | |
| 117 | 117 | <h2 id="md-steps">Steps</h2> | |
| 118 | 118 | <p>Run it.</p> | |
| 119 | - | <pre> | |
| 119 | + | <pre class="chroma"> | |
| 120 | 120 | <code class="language-sh">make all | |
| 121 | 121 | </code> | |
| 122 | 122 | </pre> | |
| @@ -116,7 +116,7 @@ | |||||
| 116 | <h1 id="md-guide">Guide</h1> | 116 | <h1 id="md-guide">Guide</h1> | ||
| 117 | <h2 id="md-steps">Steps</h2> | 117 | <h2 id="md-steps">Steps</h2> | ||
| 118 | <p>Run it.</p> | 118 | <p>Run it.</p> | ||
| 119 | - | <pre> | 119 | + | <pre class="chroma"> |
| 120 | <code class="language-sh">make all | 120 | <code class="language-sh">make all | ||
| 121 | </code> | 121 | </code> | ||
| 122 | </pre> | 122 | </pre> | ||
M internal/app/testdata/web/summary.html +1 -1
| @@ -103,7 +103,7 @@ | |||
| 103 | 103 | <h1 id="md-demo">Demo</h1> | |
| 104 | 104 | <p>A small <em>demo</em> with a <a href="/demo/blob/main/docs/guide.md">guide</a> and <a href="https://example.org/x" rel="nofollow noopener noreferrer">the site</a>.</p> | |
| 105 | 105 | <h2 id="md-install">Install</h2> | |
| 106 | - | <pre> | |
| 106 | + | <pre class="chroma"> | |
| 107 | 107 | <code class="language-sh">go install example.org/demo@latest | |
| 108 | 108 | </code> | |
| 109 | 109 | </pre> | |
| @@ -103,7 +103,7 @@ | |||||
| 103 | <h1 id="md-demo">Demo</h1> | 103 | <h1 id="md-demo">Demo</h1> | ||
| 104 | <p>A small <em>demo</em> with a <a href="/demo/blob/main/docs/guide.md">guide</a> and <a href="https://example.org/x" rel="nofollow noopener noreferrer">the site</a>.</p> | 104 | <p>A small <em>demo</em> with a <a href="/demo/blob/main/docs/guide.md">guide</a> and <a href="https://example.org/x" rel="nofollow noopener noreferrer">the site</a>.</p> | ||
| 105 | <h2 id="md-install">Install</h2> | 105 | <h2 id="md-install">Install</h2> | ||
| 106 | - | <pre> | 106 | + | <pre class="chroma"> |
| 107 | <code class="language-sh">go install example.org/demo@latest | 107 | <code class="language-sh">go install example.org/demo@latest | ||
| 108 | </code> | 108 | </code> | ||
| 109 | </pre> | 109 | </pre> | ||