Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
comment:
layout: "condensed_header, diff, flags, components"

flag_management:
default_rules:
carryforward: true

component_management:
individual_components:
- component_id: crashtracker # this is an identifier that should not be changed
Expand Down
29 changes: 15 additions & 14 deletions .github/actions/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/actions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[workspace]
members = [
"ci-shared",
"ci-crates",
"crates-reporter",
"clippy-annotation-reporter",
]
resolver = "2"
5 changes: 0 additions & 5 deletions .github/actions/ci-crates/src/lib.rs

This file was deleted.

1 change: 1 addition & 0 deletions .github/actions/ci-shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ publish = false

[dependencies]
anyhow = "1.0"
cargo_metadata = "0.23.1"
log = "0.4"
toml = "0.8"
serde = { version = "1", features = ["derive"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use anyhow::{bail, Context, Result};
use std::process::Command;

/// Run `git fetch --depth=1 origin <base_ref>` to ensure the base ref is available locally.
pub fn fetch_base(base_ref: &str) -> Result<()> {
log::info!("Fetching base branch: {base_ref}");

Expand All @@ -18,16 +17,12 @@ pub fn fetch_base(base_ref: &str) -> Result<()> {
.context("Failed to run git fetch")?;

if !status.success() {
// Non-fatal: warn but do not abort (mirrors `|| true` in the bash version)
log::warn!("git fetch for {base_ref} returned non-zero exit code; continuing");
}

Ok(())
}

/// Return the list of files changed between `origin/<base_ref>...HEAD` (three-dot diff).
///
/// Uses `git diff --name-only origin/<base_ref>...HEAD`.
pub fn changed_files(base_ref: &str) -> Result<Vec<String>> {
let output = Command::new("git")
.args(["diff", "--name-only", &format!("origin/{base_ref}...HEAD")])
Expand Down
2 changes: 2 additions & 0 deletions .github/actions/ci-shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@

pub mod crate_detection;
pub mod github_output;
pub mod git;
pub mod workspace;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::collections::{HashMap, HashSet, VecDeque};
/// Parsed workspace metadata with reverse-dependency index.
pub struct WorkspaceMetadata {
packages: Vec<Package>,
/// Maps each crate name to the list of workspace crates that depend on it.
reverse_deps: HashMap<String, Vec<String>>,
workspace_root: Utf8PathBuf,
}
Expand Down Expand Up @@ -105,8 +104,6 @@ mod tests {
s.iter().map(|s| s.to_string()).collect()
}

// --- affected_from ---

#[test]
fn affected_from_empty_seeds_returns_empty() {
let meta = make_meta(&[]);
Expand Down Expand Up @@ -171,8 +168,6 @@ mod tests {
);
}

// --- load() integration ---

#[test]
fn load_returns_non_empty_workspace() {
let meta = load().expect("load() should succeed against the real workspace");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! including finding existing comments and updating or creating comments.

use anyhow::{Context as _, Result};
use log::{error, info};
use log::info;
use octocrab::Octocrab;

/// Post or update a comment on a PR with the given report
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
# SPDX-License-Identifier: Apache-2.0

[package]
name = "ci-crates"
name = "crates-reporter"
version = "0.1.0"
edition = "2021"
rust-version = "1.84.1"
description = "GitHub Action for reporting modified crates and transitive dependencies"
homepage = "https://github.com/DataDog/libdatadog/tree/main/.github/actions/changed-crates"
repository = "https://github.com/DataDog/libdatadog/tree/main/.github/actions/changed-crates"
publish = false

[[bin]]
name = "changed-crates"
path = "src/bin/changed_crates.rs"

[dependencies]
ci-shared = { path = "../ci-shared" }
anyhow = "1.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ runs:
shell: bash
run: |
cd ${{ github.action_path }}/..
cargo build --release -p ci-crates
cargo build --release -p crates-reporter

- name: Run change reporter
id: detect
Expand All @@ -58,7 +58,7 @@ runs:
echo "status=skipped" >> $GITHUB_OUTPUT
exit 0
fi
if RUST_LOG=debug ${{ github.action_path }}/../target/release/changed-crates $PR_BASE_REF; then
if RUST_LOG=debug ${{ github.action_path }}/../target/release/crates-reporter $PR_BASE_REF; then
echo "status=success" >> $GITHUB_OUTPUT
else
echo "status=skipped" >> $GITHUB_OUTPUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
use anyhow::{anyhow, Result};
use cargo_metadata::camino::Utf8Path;
use cargo_metadata::Package;
use ci_crates::git;
use ci_crates::workspace;
use ci_shared::git;
use ci_shared::workspace;
use ci_shared::crate_detection::CrateInfo;
use ci_shared::github_output::set_output;
use std::collections::HashSet;

fn main() -> Result<()> {
env_logger::init();
// Parse args
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
return Err(anyhow!("A reference base needs to be passed"));
Expand All @@ -35,13 +34,6 @@ fn main() -> Result<()> {
let changed_files = git::changed_files(&base_ref)?;
log::info!("Changed files: {:?}", changed_files);

// TODO: Check heuristics when workspace manifest (Cargo.toml) or config.toml changed. This could indicate a
// change in:
// * Rust version.
// * Edition.
// * Profile.
// * Compilation flags.

let workspace = workspace::load()?;
let changed_crates = collect_changed_crates(&changed_files, workspace.members(), workspace.workspace_root());

Expand Down
108 changes: 99 additions & 9 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,62 @@
name: Coverage

on:
pull_request:
push:
branches:
# Allowing to generate coverage when pushes are made to main in order to generate all independent crate reports
# so we can establish a proper baseline without manual intervention or a manual workflow dispatch.
- main
pull_request:
types: ['opened', 'edited', 'reopened', 'synchronize']
branches-ignore:
- "v[0-9]+.[0-9]+.[0-9]+.[0-9]+"
- release

jobs:
setup:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.set-packages.outputs.packages }}
packages-count: ${{ steps.set-packages.outputs.packages-count }}
crates-json: ${{ steps.set-packages.outputs.crates-json }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
fetch-depth: 0
- name: Get changed crates
if: ${{ github.event_name == 'pull_request' }}
id: changed-crates
uses: ./.github/actions/changed-crates
- name: Set packages to get coverage
id: set-packages
env:
CHANGED_CRATES_COUNT: ${{ steps.changed-crates.outputs.crates_count }}
AFFECTED_CRATES: ${{ steps.changed-crates.outputs.affected_crates }}
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
COUNT="1"
PACKAGES=""
CRATES_JSON=""
elif [[ "$CHANGED_CRATES_COUNT" == "0" ]]; then
COUNT="0"
PACKAGES=""
CRATES_JSON=""
else
COUNT=$(echo "$AFFECTED_CRATES" | jq 'length')
PACKAGES=$(echo "$AFFECTED_CRATES" | jq -r 'map("-p " + .) | join(" ")')
CRATES_JSON="$AFFECTED_CRATES"
fi
echo "packages-count=$COUNT" >> $GITHUB_OUTPUT
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
{
echo "crates-json<<EOF"
echo "$CRATES_JSON"
echo "EOF"
} >> $GITHUB_OUTPUT

coverage:
needs: setup
if: needs.setup.outputs.packages-count != '0'
runs-on:
labels: ubuntu-latest-16-cores
group: APM Larger Runners
Expand Down Expand Up @@ -40,13 +89,54 @@ jobs:
cache-targets: true # cache build artifacts
cache-bin: true # cache the ~/.cargo/bin directory
- name: Generate code coverage (including doc tests)
env:
PACKAGES: ${{ needs.setup.outputs.packages }}
CRATES_JSON: ${{ needs.setup.outputs.crates-json }}
run: |
cargo llvm-cov --all-features --workspace --no-report nextest
cargo llvm-cov --all-features --workspace --no-report --doc
cargo llvm-cov report --doctests --lcov --output-path lcov.info
if [[ -z "$PACKAGES" ]]; then
cargo llvm-cov --all-features --workspace --no-report nextest
cargo llvm-cov --all-features --workspace --no-report --doc
CRATES_JSON=$(cargo metadata --no-deps --format-version 1 | jq '[.packages[].name]')
else
# shellcheck disable=SC2086 - word splitting on $PACKAGES is intentional
cargo llvm-cov --all-features --no-report nextest $PACKAGES
# shellcheck disable=SC2086
cargo llvm-cov --all-features --no-report --doc $PACKAGES
fi
for crate in $(echo "$CRATES_JSON" | jq -r '.[]'); do
if ! cargo llvm-cov report --doctests --lcov \
--output-path "lcov-${crate}.info" \
--package "${crate}"; then
if [[ -s "lcov-${crate}.info" ]]; then
echo "::error::Coverage report generation failed for ${crate}"
exit 1
else
echo "No coverage data for ${crate}, skipping"
fi
fi
done
{
echo "CRATES_JSON_COMPUTED<<EOF"
echo "$CRATES_JSON"
echo "EOF"
} >> "$GITHUB_ENV"
- name: Install Codecov CLI
run: |
curl -Os https://cli.codecov.io/v10.4.0/linux/codecov
curl -Os https://cli.codecov.io/v10.4.0/linux/codecov.SHA256SUM
echo "0f7aadde579ebde1443ad2f977beada703f562997fdda603f213faf2a8559868 codecov" | shasum -a 256 -c
chmod +x codecov
sudo mv codecov /usr/local/bin/codecov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # 5.5.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
for crate in $(echo "$CRATES_JSON_COMPUTED" | jq -r '.[]'); do
if [[ -s "lcov-${crate}.info" ]]; then
codecov upload-process \
--token "$CODECOV_TOKEN" \
--file "lcov-${crate}.info" \
--flag "${crate}" \
--fail-on-error
fi
done
Loading