Skip to content

Commit 5e86676

Browse files
authored
Improve CI workflow (#130)
Make sure workflow has no permissions. Make sure at most one workflow is running per pull request. Save the cache if it was modified (improves on #122).
1 parent 8a9537c commit 5e86676

File tree

3 files changed

+71
-22
lines changed

3 files changed

+71
-22
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ jobs:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- uses: actions/checkout@v4
16-
- run: rustup install nightly
17-
- run: rustup component add --toolchain=nightly clippy miri rustfmt
18-
- uses: actions/cache@v4
16+
- uses: actions/cache/restore@v4
1917
with:
2018
key: cargo-home-${{ runner.os }}
2119
path: |
2220
~/.cargo/bin
2321
~/.cargo/.crates*
22+
- id: before
23+
run: echo snapshot="$(cargo install --list | sha256sum)" >> $GITHUB_OUTPUT
24+
- run: rustup install nightly
25+
- run: rustup component add --toolchain=nightly clippy miri rustfmt
2426
- run: cargo +nightly install cargo-audit --locked
2527
- name: cd lib && cargo +nightly fmt -- --check
2628
run: cargo +nightly fmt -- --check
@@ -270,6 +272,15 @@ jobs:
270272
working-directory: lib/macro
271273
- run: cd lib/macro && rm Cargo.lock
272274
- run: cd lib/macro && mv Cargo.lock.backup Cargo.lock
275+
- id: after
276+
run: echo snapshot="$(cargo install --list | sha256sum)" >> $GITHUB_OUTPUT
277+
- if: ${{ steps.before.outputs.snapshot != steps.after.outputs.snapshot }}
278+
uses: actions/cache/save@v4
279+
with:
280+
key: cargo-home-${{ runner.os }}
281+
path: |
282+
~/.cargo/bin
283+
~/.cargo/.crates*
273284
windows:
274285
runs-on: windows-latest
275286
steps:
@@ -391,3 +402,7 @@ jobs:
391402
working-directory: lib/macro
392403
- run: cd lib/macro && rm Cargo.lock
393404
- run: cd lib/macro && mv Cargo.lock.backup Cargo.lock
405+
concurrency:
406+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
407+
group: ci-${{ github.ref }}
408+
permissions: {}

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: coverage
1+
name: Coverage
22

33
on:
44
push:

xtask/src/main.rs

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ struct Workflow {
327327
name: String,
328328
on: WorkflowOn,
329329
jobs: BTreeMap<String, WorkflowJob>,
330+
concurrency: BTreeMap<String, String>,
331+
permissions: BTreeMap<String, String>,
330332
}
331333

332334
#[derive(Serialize)]
@@ -358,6 +360,10 @@ struct WorkflowStep {
358360
#[serde(skip_serializing_if = "Option::is_none")]
359361
name: Option<String>,
360362
#[serde(skip_serializing_if = "Option::is_none")]
363+
id: Option<String>,
364+
#[serde(skip_serializing_if = "Option::is_none")]
365+
r#if: Option<String>,
366+
#[serde(skip_serializing_if = "Option::is_none")]
361367
uses: Option<String>,
362368
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
363369
env: BTreeMap<String, String>,
@@ -381,15 +387,44 @@ impl Flags {
381387
pull_request: WorkflowEvents { branches: vec!["main".to_owned()] },
382388
schedule: vec![WorkflowSchedule { cron: "38 11 * * 6".to_owned() }],
383389
},
390+
concurrency: BTreeMap::new(),
391+
permissions: BTreeMap::new(),
384392
jobs: BTreeMap::new(),
385393
};
394+
ci.concurrency.insert("group".to_string(), "ci-${{ github.ref }}".to_string());
395+
ci.concurrency.insert(
396+
"cancel-in-progress".to_string(),
397+
"${{ github.event_name == 'pull_request' }}".to_string(),
398+
);
386399
for actions in actions.chunk_by(|x, y| x.os == y.os) {
387400
let mut job =
388401
WorkflowJob { runs_on: format!("{}-latest", actions[0].os), steps: vec![] };
389402
job.steps.push(WorkflowStep {
390403
uses: Some("actions/checkout@v4".to_owned()),
391404
..Default::default()
392405
});
406+
let use_cache = matches!(
407+
actions[0],
408+
Action { os: Os::Ubuntu, toolchain: Toolchain::Nightly, .. }
409+
);
410+
let with = [
411+
("path".to_string(), "~/.cargo/bin\n~/.cargo/.crates*\n".to_string()),
412+
("key".to_string(), "cargo-home-${{ runner.os }}".to_string()),
413+
];
414+
let snapshot =
415+
"echo snapshot=\"$(cargo install --list | sha256sum)\" >> $GITHUB_OUTPUT";
416+
if use_cache {
417+
job.steps.push(WorkflowStep {
418+
uses: Some("actions/cache/restore@v4".to_owned()),
419+
with: with.iter().cloned().collect(),
420+
..Default::default()
421+
});
422+
job.steps.push(WorkflowStep {
423+
id: Some("before".to_string()),
424+
run: Some(snapshot.to_string()),
425+
..Default::default()
426+
});
427+
}
393428
for actions in actions.chunk_by(|x, y| x.toolchain == y.toolchain) {
394429
job.steps.push(WorkflowStep {
395430
run: Some(format!("rustup install {}", actions[0].toolchain)),
@@ -415,24 +450,6 @@ impl Flags {
415450
}
416451
job.steps.push(WorkflowStep { run: Some(run), ..Default::default() });
417452
}
418-
if matches!(
419-
actions[0],
420-
Action { os: Os::Ubuntu, toolchain: Toolchain::Nightly, .. }
421-
) {
422-
job.steps.push(WorkflowStep {
423-
uses: Some("actions/cache@v4".to_owned()),
424-
with: [
425-
(
426-
"path".to_owned(),
427-
"~/.cargo/bin\n~/.cargo/.crates*\n".to_owned(),
428-
),
429-
("key".to_owned(), "cargo-home-${{ runner.os }}".to_owned()),
430-
]
431-
.into_iter()
432-
.collect(),
433-
..Default::default()
434-
});
435-
}
436453
for task in [Task::Audit, Task::SemverChecks] {
437454
if actions.iter().any(|x| x.task == task) {
438455
job.steps.push(WorkflowStep {
@@ -451,6 +468,23 @@ impl Flags {
451468
}
452469
}
453470
}
471+
if use_cache {
472+
job.steps.push(WorkflowStep {
473+
id: Some("after".to_string()),
474+
run: Some(snapshot.to_string()),
475+
..Default::default()
476+
});
477+
job.steps.push(WorkflowStep {
478+
uses: Some("actions/cache/save@v4".to_owned()),
479+
with: with.iter().cloned().collect(),
480+
r#if: Some(
481+
"${{ steps.before.outputs.snapshot != \
482+
steps.after.outputs.snapshot }}"
483+
.to_string(),
484+
),
485+
..Default::default()
486+
});
487+
}
454488
ci.jobs.insert(actions[0].os.to_string(), job);
455489
}
456490
let ci = serde_yaml::to_string(&ci).unwrap();

0 commit comments

Comments
 (0)