Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
547eaca
Convert `ShardedHashMap` to use `hashbrown::HashTable`
cuviper Feb 27, 2025
01795b1
change definitely non-productive cycles to error
lcnr Feb 27, 2025
18809a2
keep inductive cycles as ambig in coherence
lcnr Feb 28, 2025
36efaf8
normalize away `-Wlinker-messages` wrappers from `rust-lld` rmake test
lqd Mar 5, 2025
b2de19e
Update bootstrap to edition 2024
Kobzol Feb 25, 2025
6a38322
Rename print_something to should_render
compiler-errors Mar 5, 2025
279377f
Fix pretty printing of parsed attrs in hir_pretty
compiler-errors Mar 5, 2025
f525b17
Remove AdtFlags::IS_ANONYMOUS and Copy/Clone condition for anonymous ADT
compiler-errors Mar 10, 2025
b827087
add tracking issue for unqualified_local_imports
RalfJung Mar 10, 2025
02bb2d4
Disable CFI for weakly linked syscalls
1c3t3a Mar 4, 2025
e5dc1e3
Add comments for #[no_sanitize(cfi)] in stdlib
1c3t3a Mar 10, 2025
fb9ce02
Limit formatting width and precision to 16 bits.
m-ou-se Feb 12, 2025
4374d54
Update tests.
m-ou-se Feb 12, 2025
ce512c2
Fix rust-analyzer for 16-bit fmt width and precision.
m-ou-se Feb 12, 2025
7677567
Remove unnecessary semicolon.
m-ou-se Feb 28, 2025
2647cf1
Add #[track_caller] to from_usize.
m-ou-se Feb 28, 2025
7ca7675
Make all keys explicit in citool
Kobzol Feb 27, 2025
112f7b0
make precise capturing args in rustdoc Json typed
Kohei316 Mar 2, 2025
0412507
Move job handling to a separate module
Kobzol Mar 10, 2025
2ce0205
Share implementation of expr_u{16,32,size}.
m-ou-se Mar 10, 2025
3326a9f
Allow using glob aliases for custom try jobs
Kobzol Mar 10, 2025
06d86cd
Modify try-job documentation
Kobzol Mar 10, 2025
dfef1a7
Handle backticks in try job patterns
Kobzol Mar 10, 2025
16c08f6
Ignore job duplicates
Kobzol Mar 10, 2025
bf58a35
stabilize `ci_rustc_if_unchanged_logic` test for local environments
onur-ozkan Mar 8, 2025
32e0ce2
remove rls support from bootstrap
onur-ozkan Mar 10, 2025
733cbb5
remove rls specific parts from tidy and build-manifest
onur-ozkan Mar 10, 2025
91f8a40
remove rls source from the repository
onur-ozkan Mar 10, 2025
a657aeb
add change entry for rls removal
onur-ozkan Mar 10, 2025
5d4ff50
Update books
rustbot Mar 10, 2025
dcf6137
use next_back() instead of last() on DoubleEndedIterator
matthiaskrgr Mar 10, 2025
e337d87
Add powerpc64le maintainers
daltenty Mar 7, 2025
d75c973
main.js: insertAfter needs non-root referenceNode
lolbinarycat Mar 10, 2025
93161f5
main.js: don't set mouseMovedAfterSearch, as it is never read
lolbinarycat Mar 10, 2025
cf7f3cf
main.js: give type signatures to a few helper functions
lolbinarycat Mar 10, 2025
da5da99
main.js: handleEscape and handleShortcut accept KeyboardEvent
lolbinarycat Mar 10, 2025
6622111
main.js: always refer to searchState through window.searchState
lolbinarycat Mar 10, 2025
f5efd2a
main.js(isDisplayed): coerce truthy values to boolean
lolbinarycat Mar 10, 2025
ab180c2
main.js: handle document.activeElement being null
lolbinarycat Mar 10, 2025
2e1c8f0
rustdoc.d.ts: window.SIDEBAR_ITEMS may exist.
lolbinarycat Mar 10, 2025
749b6bf
rustdoc.d.ts: add window.{register_implementors,pending_implementors}
lolbinarycat Mar 10, 2025
7421546
main.js: typecheck things related to window.register_type_impls
lolbinarycat Mar 10, 2025
20bac26
main.js: remove searchState from globals.
lolbinarycat Mar 10, 2025
fb3d9ce
Rollup merge of #126856 - onur-ozkan:remove-rls, r=clubby789
jieyouxu Mar 10, 2025
12f29ff
Rollup merge of #136932 - m-ou-se:fmt-width-precision-u16, r=scottmcm
jieyouxu Mar 10, 2025
4e80159
Rollup merge of #137314 - lcnr:cycles-with-unknown-kind, r=compiler-e…
jieyouxu Mar 10, 2025
5923d2c
Rollup merge of #137612 - Kobzol:bootstrap-2024, r=onur-ozkan
jieyouxu Mar 10, 2025
5763e83
Rollup merge of #137701 - cuviper:sharded-hashtable, r=fmease
jieyouxu Mar 10, 2025
002b97a
Rollup merge of #138002 - 1c3t3a:fix-std-cfi-violation, r=rcvalle
jieyouxu Mar 10, 2025
4cbf318
Rollup merge of #138052 - lqd:lld-linker-messages, r=jieyouxu
jieyouxu Mar 10, 2025
de3720b
Rollup merge of #138063 - compiler-errors:improve-attr-unpretty, r=jd…
jieyouxu Mar 10, 2025
caf177d
Rollup merge of #138109 - Kohei316:feat/rust-doc-precise-capturing-ar…
jieyouxu Mar 10, 2025
41fc858
Rollup merge of #138147 - daltenty:patch-1, r=jieyouxu
jieyouxu Mar 10, 2025
f6b7134
Rollup merge of #138245 - onur-ozkan:ci-rustc-test-fix, r=jieyouxu
jieyouxu Mar 10, 2025
7956fc6
Rollup merge of #138296 - compiler-errors:deanonymous, r=lcnr
jieyouxu Mar 10, 2025
1a275d7
Rollup merge of #138300 - RalfJung:unqualified-local-imports, r=jieyouxu
jieyouxu Mar 10, 2025
8d3416e
Rollup merge of #138307 - Kobzol:citool-alias, r=marcoieni
jieyouxu Mar 10, 2025
4cbeefb
Rollup merge of #138313 - rustbot:docs-update, r=ehuss
jieyouxu Mar 10, 2025
7742eda
Rollup merge of #138315 - matthiaskrgr:nextback, r=fmease
jieyouxu Mar 10, 2025
0b4f8df
Rollup merge of #138318 - lolbinarycat:rustdoc-js-less-expect-error-p…
jieyouxu Mar 10, 2025
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
Prev Previous commit
Next Next commit
Move job handling to a separate module
  • Loading branch information
Kobzol committed Mar 10, 2025
commit 0412507c52d074e20dc47501078d24c4ab51294f
233 changes: 233 additions & 0 deletions src/ci/citool/src/jobs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
use crate::{GitHubContext, utils};
use serde_yaml::Value;
use std::collections::BTreeMap;
use std::path::Path;

use serde_yaml::Value;

use crate::GitHubContext;

/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file.
#[derive(serde::Deserialize, Debug, Clone)]
pub struct Job {
/// Name of the job, e.g. mingw-check
pub name: String,
/// GitHub runner on which the job should be executed
pub os: String,
pub env: BTreeMap<String, Value>,
/// Should the job be only executed on a specific channel?
#[serde(default)]
pub only_on_channel: Option<String>,
/// Do not cancel the whole workflow if this job fails.
#[serde(default)]
pub continue_on_error: Option<bool>,
/// Free additional disk space in the job, by removing unused packages.
#[serde(default)]
pub free_disk: Option<bool>,
}

impl Job {
/// By default, the Docker image of a job is based on its name.
/// However, it can be overridden by its IMAGE environment variable.
pub fn image(&self) -> String {
self.env
.get("IMAGE")
.map(|v| v.as_str().expect("IMAGE value should be a string").to_string())
.unwrap_or_else(|| self.name.clone())
}

fn is_linux(&self) -> bool {
self.os.contains("ubuntu")
}
}

#[derive(serde::Deserialize, Debug)]
struct JobEnvironments {
#[serde(rename = "pr")]
pr_env: BTreeMap<String, Value>,
#[serde(rename = "try")]
try_env: BTreeMap<String, Value>,
#[serde(rename = "auto")]
auto_env: BTreeMap<String, Value>,
}

#[derive(serde::Deserialize, Debug)]
pub struct JobDatabase {
#[serde(rename = "pr")]
pub pr_jobs: Vec<Job>,
#[serde(rename = "try")]
pub try_jobs: Vec<Job>,
#[serde(rename = "auto")]
pub auto_jobs: Vec<Job>,

/// Shared environments for the individual run types.
envs: JobEnvironments,
}

impl JobDatabase {
fn find_auto_job_by_name(&self, name: &str) -> Option<Job> {
self.auto_jobs.iter().find(|j| j.name == name).cloned()
}
}

pub fn load_job_db(path: &Path) -> anyhow::Result<JobDatabase> {
let db = utils::read_to_string(path)?;
let mut db: Value = serde_yaml::from_str(&db)?;

// We need to expand merge keys (<<), because serde_yaml can't deal with them
// `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges.
db.apply_merge()?;
db.apply_merge()?;

let db: JobDatabase = serde_yaml::from_value(db)?;
Ok(db)
}

/// Representation of a job outputted to a GitHub Actions workflow.
#[derive(serde::Serialize, Debug)]
struct GithubActionsJob {
/// The main identifier of the job, used by CI scripts to determine what should be executed.
name: String,
/// Helper label displayed in GitHub Actions interface, containing the job name and a run type
/// prefix (PR/try/auto).
full_name: String,
os: String,
env: BTreeMap<String, serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
continue_on_error: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
free_disk: Option<bool>,
}

/// Skip CI jobs that are not supposed to be executed on the given `channel`.
fn skip_jobs(jobs: Vec<Job>, channel: &str) -> Vec<Job> {
jobs.into_iter()
.filter(|job| {
job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel)
})
.collect()
}

/// Type of workflow that is being executed on CI
#[derive(Debug)]
pub enum RunType {
/// Workflows that run after a push to a PR branch
PullRequest,
/// Try run started with @bors try
TryJob { custom_jobs: Option<Vec<String>> },
/// Merge attempt workflow
AutoJob,
}

/// Maximum number of custom try jobs that can be requested in a single
/// `@bors try` request.
const MAX_TRY_JOBS_COUNT: usize = 20;

fn calculate_jobs(
run_type: &RunType,
db: &JobDatabase,
channel: &str,
) -> anyhow::Result<Vec<GithubActionsJob>> {
let (jobs, prefix, base_env) = match run_type {
RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env),
RunType::TryJob { custom_jobs } => {
let jobs = if let Some(custom_jobs) = custom_jobs {
if custom_jobs.len() > MAX_TRY_JOBS_COUNT {
return Err(anyhow::anyhow!(
"It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs",
custom_jobs.len()
));
}

let mut jobs = vec![];
let mut unknown_jobs = vec![];
for custom_job in custom_jobs {
if let Some(job) = db.find_auto_job_by_name(custom_job) {
jobs.push(job);
} else {
unknown_jobs.push(custom_job.clone());
}
}
if !unknown_jobs.is_empty() {
return Err(anyhow::anyhow!(
"Custom job(s) `{}` not found in auto jobs",
unknown_jobs.join(", ")
));
}
jobs
} else {
db.try_jobs.clone()
};
(jobs, "try", &db.envs.try_env)
}
RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env),
};
let jobs = skip_jobs(jobs, channel);
let jobs = jobs
.into_iter()
.map(|job| {
let mut env: BTreeMap<String, serde_json::Value> = crate::yaml_map_to_json(base_env);
env.extend(crate::yaml_map_to_json(&job.env));
let full_name = format!("{prefix} - {}", job.name);

GithubActionsJob {
name: job.name,
full_name,
os: job.os,
env,
continue_on_error: job.continue_on_error,
free_disk: job.free_disk,
}
})
.collect();

Ok(jobs)
}

pub fn calculate_job_matrix(
db: JobDatabase,
gh_ctx: GitHubContext,
channel: &str,
) -> anyhow::Result<()> {
let run_type = gh_ctx.get_run_type().ok_or_else(|| {
anyhow::anyhow!("Cannot determine the type of workflow that is being executed")
})?;
eprintln!("Run type: {run_type:?}");

let jobs = calculate_jobs(&run_type, &db, channel)?;
if jobs.is_empty() {
return Err(anyhow::anyhow!("Computed job list is empty"));
}

let run_type = match run_type {
RunType::PullRequest => "pr",
RunType::TryJob { .. } => "try",
RunType::AutoJob => "auto",
};

eprintln!("Output");
eprintln!("jobs={jobs:?}");
eprintln!("run_type={run_type}");
println!("jobs={}", serde_json::to_string(&jobs)?);
println!("run_type={run_type}");

Ok(())
}

pub fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> {
let Some(job) = jobs.iter().find(|j| j.name == name) else {
let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect();
let mut available_jobs =
available_jobs.iter().map(|j| j.name.to_string()).collect::<Vec<_>>();
available_jobs.sort();
return Err(anyhow::anyhow!(
"Job {name} not found. The following jobs are available:\n{}",
available_jobs.join(", ")
));
};
if !job.is_linux() {
return Err(anyhow::anyhow!("Only Linux jobs can be executed locally"));
}

Ok(job)
}
Loading