Skip to content

ci/eval: re-implement compare in nix#362844

Merged
Mic92 merged 1 commit intoNixOS:masterfrom
GaetanLepage:compare-nix
Dec 9, 2024
Merged

ci/eval: re-implement compare in nix#362844
Mic92 merged 1 commit intoNixOS:masterfrom
GaetanLepage:compare-nix

Conversation

@GaetanLepage
Copy link
Contributor

@GaetanLepage GaetanLepage commented Dec 7, 2024

Things done

This is a reimplementation in nix of the current compare.jq logic.
Later, I will add more information in the produced JSON (so that we can use this in nixpkgs-review).
For now, this is a strict equivalent of the previous jq implementation.

There is one logic change that might be acceptable:
If a package foo existed, but was not available on platform aarch64-darwin and the PR makes it available for this platform, should it be listed as an added package or as a changed one ?
The current implementation lists it in changed while the new one consider puts it in changed.
This should not be too hard to change.

Please, feel free to criticize the implementation details and propose some refactoring.
It might lack some commenting and also variable names could be wiser.

cc @Mic92 @infinisil

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 25.05 Release Notes (or backporting 24.11 and 25.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added the 6.topic: continuous integration Affects continuous integration (CI) in Nixpkgs, including Ofborg and GitHub Actions label Dec 7, 2024
@github-actions github-actions bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. labels Dec 7, 2024
Comment on lines +28 to +32
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could put those in the toJSON call below but it would require a rec. I don't know what is the recommended way.

Copy link
Member

@JohnRTitor JohnRTitor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would open a test PR targeting your fork's branch, to test the action, if I were you.

Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as it works, both in GHA's and using a local nix-build ci -A eval.compare ..., this LGTM!

@paparodeo
Copy link
Contributor

paparodeo commented Dec 7, 2024

Looks good. FWIW I did this in sql and added stats ex1, ex2, ex3, ex4.

I think the rebuilds should be done by paths rather than attributes given there is a many to one mapping of attrs to paths. ofborg will treat a new for platform path as a new package (it gets the new package label).

@JohnRTitor
Copy link
Member

added stats ex1, ex2, ex3, ex4.

looks superb to me!

@GaetanLepage
Copy link
Contributor Author

GaetanLepage commented Dec 7, 2024

Looks good. FWIW I did this in sql and added stats ex1, ex2, ex3, ex4.

Oh wow, this looks fancy !
Would you prefer that we have your implementation instead of mine ?
The motivation behind this PR is to later be able to add more information in the json (i.e. what to rebuild for each platform).

I think the rebuilds should be done by paths rather than attributes given there is a many to one mapping of attrs to paths. ofborg will treat a new for platform path as a new package (it gets the new package label).

It is kind of already the case no ? Here are the definitions I went with. Note: By "item" I mean a tuple (platform, name) (ex: python312Packages.torch.x86_64-linux).

  • added: any item that was not present before and now exists.
  • removed: any item that was present before and is not anymore.
  • changed: any item that was present before and is still there but which value has changed. By value, I mean its set of out-paths.

At this stage, tinymist.x86_64-linux could be changed, while tinymist.x86_64-darwin removed and tinymist.aarch64-darwin added.

Now, where this gets slightly tricky is that we don't report those affected items directly but only their names. I.e. we need to get rid of the platform. While in most cases, a single name will only end up in a single category, our (artificial) example of tinymist is hard to categorize.
Currently, the implementation will extract, for each category (added, removed and changed) the set of package names.
This means, that tinymist would here be listed in all three categories.

Having said that, this is not too crucial because what really counts is the number of rebuilds. The definition of rebuilds is precise and consensual:

#rebuilds = |added| + |changed|

where added and changed are items sets and are disjoint by construction.

@GaetanLepage
Copy link
Contributor Author

@infinisil if you are happy with it, feel free to merge this PR.
I would directly open a follow up to add a raw-er list of "rebuilds" to the JSON so that we can leverage this result in nixpkgs-review.

@paparodeo
Copy link
Contributor

Looks good. FWIW I did this in sql and added stats ex1, ex2, ex3, ex4.

Oh wow, this looks fancy ! Would you prefer that we have your implementation instead of mine ? The motivation behind this PR is to later be able to add more information in the json (i.e. what to rebuild for each platform).

It is up to the CI team tho I get the impression that a nix implementation is preferred. I find duckdb is pretty handy to query json files but am not sure how others feel about sql.

the sql implementation emits a json file which can be use to query what to build for each platform. eg:

$ jq -r '.[]|select(.action != "remove")| [.machine + "-" + .os, .attr]|@tsv' < changed.json |head
aarch64-darwin  _64gram
x86_64-darwin   _64gram
aarch64-darwin  bolt_19
aarch64-linux   bolt_19
x86_64-darwin   bolt_19
x86_64-linux    bolt_19
aarch64-darwin  bpf-linker
aarch64-linux   bpf-linker
x86_64-darwin   bpf-linker
x86_64-linux    bpf-linker

I think the rebuilds should be done by paths rather than attributes given there is a many to one mapping of attrs to paths. ofborg will treat a new for platform path as a new package (it gets the new package label).

It is kind of already the case no ? Here are the definitions I went with. Note: By "item" I mean a tuple (platform, name) (ex: python312Packages.torch.x86_64-linux).

  • added: any item that was not present before and now exists.
  • removed: any item that was present before and is not anymore.
  • changed: any item that was present before and is still there but which value has changed. By value, I mean its set of out-paths.

At this stage, tinymist.x86_64-linux could be changed, while tinymist.x86_64-darwin removed and tinymist.aarch64-darwin added.

Now, where this gets slightly tricky is that we don't report those affected items directly but only their names. I.e. we need to get rid of the platform. While in most cases, a single name will only end up in a single category, our (artificial) example of tinymist is hard to categorize. Currently, the implementation will extract, for each category (added, removed and changed) the set of package names. This means, that tinymist would here be listed in all three categories.

Having said that, this is not too crucial because what really counts is the number of rebuilds. The definition of rebuilds is precise and consensual:

#rebuilds = |added| + |removed|

where added and removed are items sets and are disjoint by construction.

did you mean #rebuilds = |added| + |changed|? this double counts as there are some attributes which map to the same path. eg: llvm_19 llvmPackages_19.llvm and llvmPackages_19.libllvm are all the same package and should only be counted as 1 rebuild but I believe that this PR will count it as 3.

can see the many to 1 mapping when looking at the output of a llvm-19 upgrade https://github.com/paparodeo/nixpkgs/actions/runs/12214197953

$ unzip comparison.zip 
$ duckdb
v1.1.3 19864453f7
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D SELECT
    attr,
    count(*) over ( PARTITION BY paths ) AS c,
    format('{}-{}', machine, os) AS target,
    md5(paths::string) AS md5,
  FROM 'changed.json'
  QUALIFY c > 2
  ORDER BY target, paths, attr;
┌────────────────────────────────┬───────┬────────────────┬──────────────────────────────────┐
│              attr              │   c   │     target     │               md5                │
│            varchar             │ int64 │    varchar     │             varchar              │
├────────────────────────────────┼───────┼────────────────┼──────────────────────────────────┤
│ llvmPackages_19.libllvm        │     3 │ aarch64-darwin │ cb679493005b2b6a9b0aa761526f2c76 │
│ llvmPackages_19.llvm           │     3 │ aarch64-darwin │ cb679493005b2b6a9b0aa761526f2c76 │
│ llvm_19                        │     3 │ aarch64-darwin │ cb679493005b2b6a9b0aa761526f2c76 │
│ clang_19                       │     3 │ aarch64-darwin │ 2a8c35d601d4e04e5554cf67c1c4ba64 │
│ llvmPackages_19.clang          │     3 │ aarch64-darwin │ 2a8c35d601d4e04e5554cf67c1c4ba64 │
│ llvmPackages_19.libcxxClang    │     3 │ aarch64-darwin │ 2a8c35d601d4e04e5554cf67c1c4ba64 │
│ clang_19                       │     3 │ aarch64-linux  │ 1862f8c3f5abde44aa4488da5dd9824e │
│ llvmPackages_19.clang          │     3 │ aarch64-linux  │ 1862f8c3f5abde44aa4488da5dd9824e │
│ llvmPackages_19.libstdcxxClang │     3 │ aarch64-linux  │ 1862f8c3f5abde44aa4488da5dd9824e │
│ llvmPackages_19.libllvm        │     3 │ aarch64-linux  │ bc1f129cf02468ed504b13a6a5443259 │
│ llvmPackages_19.llvm           │     3 │ aarch64-linux  │ bc1f129cf02468ed504b13a6a5443259 │
│ llvm_19                        │     3 │ aarch64-linux  │ bc1f129cf02468ed504b13a6a5443259 │
│ clang_19                       │     3 │ x86_64-darwin  │ 48872f71dbcd65d57932fba81972b068 │
│ llvmPackages_19.clang          │     3 │ x86_64-darwin  │ 48872f71dbcd65d57932fba81972b068 │
│ llvmPackages_19.libcxxClang    │     3 │ x86_64-darwin  │ 48872f71dbcd65d57932fba81972b068 │
│ llvmPackages_19.libllvm        │     3 │ x86_64-darwin  │ b18287690eda354205d320f1429a1f44 │
│ llvmPackages_19.llvm           │     3 │ x86_64-darwin  │ b18287690eda354205d320f1429a1f44 │
│ llvm_19                        │     3 │ x86_64-darwin  │ b18287690eda354205d320f1429a1f44 │
│ llvmPackages_19.libllvm        │     3 │ x86_64-linux   │ 40a63b8cf2fac5fbe4a4f3623bb10b52 │
│ llvmPackages_19.llvm           │     3 │ x86_64-linux   │ 40a63b8cf2fac5fbe4a4f3623bb10b52 │
│ llvm_19                        │     3 │ x86_64-linux   │ 40a63b8cf2fac5fbe4a4f3623bb10b52 │
│ clang_19                       │     3 │ x86_64-linux   │ d1a744b78d295a6675f8178ab9b9dcc5 │
│ llvmPackages_19.clang          │     3 │ x86_64-linux   │ d1a744b78d295a6675f8178ab9b9dcc5 │
│ llvmPackages_19.libstdcxxClang │     3 │ x86_64-linux   │ d1a744b78d295a6675f8178ab9b9dcc5 │
├────────────────────────────────┴───────┴────────────────┴──────────────────────────────────┤
│ 24 rows                                                                          4 columns │
└────────────────────────────────────────────────────────────────────────────────────────────┘

@GaetanLepage
Copy link
Contributor Author

It is up to the CI team tho I get the impression that a nix implementation is preferred.

Definitely.

I find duckdb is pretty handy to query json files but am not sure how others feel about sql.

Your implementation looks very nice indeed ! I am not too familiar with SQL and would be unable to maintain it. However if it does the job and is preferred by the CI team, I would be fine with it of course.

did you mean #rebuilds = |added| + |changed|?

Yes. I have corrected my previous message, thanks.

this double counts as there are some attributes which map to the same path. eg: llvm_19 llvmPackages_19.llvm and llvmPackages_19.libllvm are all the same package and should only be counted as 1 rebuild but I believe that this PR will count it as 3.

Very true. Now I understand your many-to-one point. I think that the current implem also suffers from this issue. I don't know how crucial it is though. Of course, having an accurate solution would be better though.

@Mic92
Copy link
Member

Mic92 commented Dec 8, 2024

Nix is probably a better cultural fit looking for the contributors than sql.

@paparodeo
Copy link
Contributor

this double counts as there are some attributes which map to the same path. eg: llvm_19 llvmPackages_19.llvm and llvmPackages_19.libllvm are all the same package and should only be counted as 1 rebuild but I believe that this PR will count it as 3.

Very true. Now I understand your many-to-one point. I think that the current implem also suffers from this issue. I don't know how crucial it is though. Of course, having an accurate solution would be better though.

yes the current implementation also has this problem. also seemed like it missed a rebuild when the meta.platforms changed from linux -> unix. eg: https://github.com/NixOS/nixpkgs/actions/runs/12178480057 the labels are now correct only due to ofborg but if looking at the changed.json it lists:

  "labels": [
    "10.rebuild-linux: 1-10",
    "10.rebuild-darwin: 0"
  ]

but darwin should also get a rebuild -- not sure if this PR has the same issue. the sql does the right thing given the same inputs.

@paparodeo
Copy link
Contributor

not sure if this PR has the same issue

this PR seems to handle https://github.com/NixOS/nixpkgs/actions/runs/12178480057 correctly (master marks darwin as 0 builds). so that's good!.

{
  "attrdiff": {
    "added": [
      "netris"
    ],
    "changed": [
      "netris"
    ],
    "removed": []
  },
  "labels": {
    "darwin": "10.rebuild-darwin: 1-10",
    "linux": "10.rebuild-linux: 1-10"
  },
  "rebuildCountByKernel": {
    "darwin": 1,
    "linux": 1
  },
  "rebuildsByKernel": {
    "darwin": [
      "netris"
    ],
    "linux": [
      "netris"
    ]
  }
}

@GaetanLepage GaetanLepage requested a review from Mic92 December 9, 2024 17:06
@GaetanLepage
Copy link
Contributor Author

Any further feedback/requests on this ?

@Mic92
Copy link
Member

Mic92 commented Dec 9, 2024

Doing a test run in Mic92#40.
Than we can merge it.

@Mic92 Mic92 merged commit 23c1faa into NixOS:master Dec 9, 2024
@GaetanLepage GaetanLepage deleted the compare-nix branch December 9, 2024 20:04
@paparodeo
Copy link
Contributor

paparodeo commented Dec 10, 2024

seems to be mis-labeling: https://github.com/NixOS/nixpkgs/actions/runs/12252092760

listed as 101-500 but should be 11-100

"labels": {
    "darwin": "10.rebuild-darwin: 101-500",
    "linux": "10.rebuild-linux: 101-500"
  },
  "rebuildCountByKernel": {
    "darwin": 11,
    "linux": 12
  },
diff --git a/ci/eval/compare/utils.nix b/ci/eval/compare/utils.nix
index 22353499d699..2794b5eda4ec 100644
--- a/ci/eval/compare/utils.nix
+++ b/ci/eval/compare/utils.nix
@@ -113,6 +113,8 @@ rec {
           "0"
         else if rebuildCount <= 10 then
           "1-10"
+        else if rebuildCount <= 100 then
+          "11-100"
         else if rebuildCount <= 500 then
           "101-500"
         else if rebuildCount <= 1000 then

@GaetanLepage
Copy link
Contributor Author

seems to be mis-labeling: https://github.com/NixOS/nixpkgs/actions/runs/12252092760

listed as 101-500 but should be 11-100

"labels": {
    "darwin": "10.rebuild-darwin: 101-500",
    "linux": "10.rebuild-linux: 101-500"
  },
  "rebuildCountByKernel": {
    "darwin": 11,
    "linux": 12
  },

Indeed, the rebuildCountByKernel is fine, so it's a bug in the label assigning code...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: continuous integration Affects continuous integration (CI) in Nixpkgs, including Ofborg and GitHub Actions 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants