···1+[run]
2+indent_style = space
3+indent_size = 2
+13
ci/github-script/README.md
···0000000000000
···1+# GitHub specific CI scripts
2+3+This folder contains [`actions/github-script`](https://github.com/actions/github-script)-based JavaScript code.
4+It provides a `nix-shell` environment to run and test these actions locally.
5+6+To run any of the scripts locally:
7+8+- Enter `nix-shell` in `./ci/github-script`.
9+- Ensure `gh` is authenticated.
10+11+## Labeler
12+13+Run `./run labels OWNER REPO`, where OWNER is your username or "NixOS" and REPO the name of your fork or "nixpkgs".
···1+module.exports = async function ({ github, core }, callback) {
2+ const Bottleneck = require('bottleneck')
3+4+ const stats = {
5+ issues: 0,
6+ prs: 0,
7+ requests: 0,
8+ artifacts: 0,
9+ }
10+11+ // Rate-Limiting and Throttling, see for details:
12+ // https://github.com/octokit/octokit.js/issues/1069#throttling
13+ // https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api
14+ const allLimits = new Bottleneck({
15+ // Avoid concurrent requests
16+ maxConcurrent: 1,
17+ // Will be updated with first `updateReservoir()` call below.
18+ reservoir: 0,
19+ })
20+ // Pause between mutative requests
21+ const writeLimits = new Bottleneck({ minTime: 1000 }).chain(allLimits)
22+ github.hook.wrap('request', async (request, options) => {
23+ // Requests to the /rate_limit endpoint do not count against the rate limit.
24+ if (options.url == '/rate_limit') return request(options)
25+ // Search requests are in a different resource group, which allows 30 requests / minute.
26+ // We do less than a handful each run, so not implementing throttling for now.
27+ if (options.url.startsWith('/search/')) return request(options)
28+ stats.requests++
29+ if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(options.method))
30+ return writeLimits.schedule(request.bind(null, options))
31+ else return allLimits.schedule(request.bind(null, options))
32+ })
33+34+ async function updateReservoir() {
35+ let response
36+ try {
37+ response = await github.rest.rateLimit.get()
38+ } catch (err) {
39+ core.error(`Failed updating reservoir:\n${err}`)
40+ // Keep retrying on failed rate limit requests instead of exiting the script early.
41+ return
42+ }
43+ // Always keep 1000 spare requests for other jobs to do their regular duty.
44+ // They normally use below 100, so 1000 is *plenty* of room to work with.
45+ const reservoir = Math.max(0, response.data.resources.core.remaining - 1000)
46+ core.info(`Updating reservoir to: ${reservoir}`)
47+ allLimits.updateSettings({ reservoir })
48+ }
49+ await updateReservoir()
50+ // Update remaining requests every minute to account for other jobs running in parallel.
51+ const reservoirUpdater = setInterval(updateReservoir, 60 * 1000)
52+53+ try {
54+ await callback(stats)
55+ } finally {
56+ clearInterval(reservoirUpdater)
57+ core.notice(
58+ `Processed ${stats.prs} PRs, ${stats.issues} Issues, made ${stats.requests + stats.artifacts} API requests and downloaded ${stats.artifacts} artifacts.`,
59+ )
60+ }
61+}
-4
ci/labels/.editorconfig
···1-# TODO: Move to <top-level>/.editorconfig, once ci/.editorconfig has made its way through staging.
2-[*.cjs]
3-indent_style = space
4-indent_size = 2
···0000
ci/labels/.gitignore
ci/github-script/.gitignore
ci/labels/.npmrc
ci/github-script/.npmrc
-4
ci/labels/README.md
···1-To test the labeler locally:
2-- Provide `gh` on `PATH` and make sure it's authenticated.
3-- Enter `nix-shell` in `./ci/labels`.
4-- Run `./run.js OWNER REPO`, where OWNER is your username or "NixOS" and REPO the name of your fork or "nixpkgs".
···0000
+8-63
ci/labels/labels.cjs
ci/github-script/labels.js
···1module.exports = async function ({ github, context, core, dry }) {
2- const Bottleneck = require('bottleneck')
3 const path = require('node:path')
4 const { DefaultArtifactClient } = require('@actions/artifact')
5 const { readFile, writeFile } = require('node:fs/promises')
067 const artifactClient = new DefaultArtifactClient()
89- const stats = {
10- issues: 0,
11- prs: 0,
12- requests: 0,
13- artifacts: 0,
14- }
15-16- // Rate-Limiting and Throttling, see for details:
17- // https://github.com/octokit/octokit.js/issues/1069#throttling
18- // https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api
19- const allLimits = new Bottleneck({
20- // Avoid concurrent requests
21- maxConcurrent: 1,
22- // Will be updated with first `updateReservoir()` call below.
23- reservoir: 0,
24- })
25- // Pause between mutative requests
26- const writeLimits = new Bottleneck({ minTime: 1000 }).chain(allLimits)
27- github.hook.wrap('request', async (request, options) => {
28- // Requests to the /rate_limit endpoint do not count against the rate limit.
29- if (options.url == '/rate_limit') return request(options)
30- // Search requests are in a different resource group, which allows 30 requests / minute.
31- // We do less than a handful each run, so not implementing throttling for now.
32- if (options.url.startsWith('/search/')) return request(options)
33- stats.requests++
34- if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(options.method))
35- return writeLimits.schedule(request.bind(null, options))
36- else return allLimits.schedule(request.bind(null, options))
37- })
38-39- async function updateReservoir() {
40- let response
41- try {
42- response = await github.rest.rateLimit.get()
43- } catch (err) {
44- core.error(`Failed updating reservoir:\n${err}`)
45- // Keep retrying on failed rate limit requests instead of exiting the script early.
46- return
47- }
48- // Always keep 1000 spare requests for other jobs to do their regular duty.
49- // They normally use below 100, so 1000 is *plenty* of room to work with.
50- const reservoir = Math.max(0, response.data.resources.core.remaining - 1000)
51- core.info(`Updating reservoir to: ${reservoir}`)
52- allLimits.updateSettings({ reservoir })
53- }
54- await updateReservoir()
55- // Update remaining requests every minute to account for other jobs running in parallel.
56- const reservoirUpdater = setInterval(updateReservoir, 60 * 1000)
57-58- async function handlePullRequest(item) {
59 const log = (k, v) => core.info(`PR #${item.number} - ${k}: ${v}`)
6061 const pull_number = item.number
···221 return prLabels
222 }
223224- async function handle(item) {
225 try {
226 const log = (k, v, skip) => {
227 core.info(`#${item.number} - ${k}: ${v}` + (skip ? ' (skipped)' : ''))
···237238 if (item.pull_request || context.payload.pull_request) {
239 stats.prs++
240- Object.assign(itemLabels, await handlePullRequest(item))
241 } else {
242 stats.issues++
243 }
···326 }
327 }
328329- try {
330 if (context.payload.pull_request) {
331- await handle(context.payload.pull_request)
332 } else {
333 const lastRun = (
334 await github.rest.actions.listWorkflowRuns({
···447 arr.findIndex((firstItem) => firstItem.number == thisItem.number),
448 )
449450- ;(await Promise.allSettled(items.map(handle)))
451 .filter(({ status }) => status == 'rejected')
452 .map(({ reason }) =>
453 core.setFailed(`${reason.message}\n${reason.cause.stack}`),
454 )
455-456- core.notice(
457- `Processed ${stats.prs} PRs, ${stats.issues} Issues, made ${stats.requests + stats.artifacts} API requests and downloaded ${stats.artifacts} artifacts.`,
458- )
459 }
460- } finally {
461- clearInterval(reservoirUpdater)
462- }
463}
···443444 pnpmDeps = pnpm.fetchDeps {
445 inherit (finalAttrs) pname version src;
446- hash = "...";
447 fetcherVersion = 2;
0448 };
449})
450```
···568 # ...
569 pnpmDeps = pnpm.fetchDeps {
570 # ...
571- hash = "..."; # you can use your already set hash here
572 fetcherVersion = 1;
0573 };
574}
575```
···581 # ...
582 pnpmDeps = pnpm.fetchDeps {
583 # ...
584- hash = "..."; # clear this hash and generate a new one
585 fetcherVersion = 2;
0586 };
587}
588```
···443444 pnpmDeps = pnpm.fetchDeps {
445 inherit (finalAttrs) pname version src;
0446 fetcherVersion = 2;
447+ hash = "...";
448 };
449})
450```
···568 # ...
569 pnpmDeps = pnpm.fetchDeps {
570 # ...
0571 fetcherVersion = 1;
572+ hash = "..."; # you can use your already set hash here
573 };
574}
575```
···581 # ...
582 pnpmDeps = pnpm.fetchDeps {
583 # ...
0584 fetcherVersion = 2;
585+ hash = "..."; # clear this hash and generate a new one
586 };
587}
588```
+2
nixos/doc/manual/release-notes/rl-2511.section.md
···131- [](#opt-services.gnome.gnome-keyring.enable) does not ship with an SSH agent anymore, as this is now handled by the `gcr_4` package instead of `gnome-keyring`. A new module has been added to support this, under [](#opt-services.gnome.gcr-ssh-agent.enable) (its default value has been set to [](#opt-services.gnome.gnome-keyring.enable) to ensure a smooth transition). See the [relevant upstream PR](https://gitlab.gnome.org/GNOME/gcr/-/merge_requests/67) for more details.
132133- The `nettools` package (ifconfig, arp, mii-tool, netstat, route) is not installed by default anymore. The suite is unmaintained and users should migrate to `iproute2` and `ethtool` instead.
00
···131- [](#opt-services.gnome.gnome-keyring.enable) does not ship with an SSH agent anymore, as this is now handled by the `gcr_4` package instead of `gnome-keyring`. A new module has been added to support this, under [](#opt-services.gnome.gcr-ssh-agent.enable) (its default value has been set to [](#opt-services.gnome.gnome-keyring.enable) to ensure a smooth transition). See the [relevant upstream PR](https://gitlab.gnome.org/GNOME/gcr/-/merge_requests/67) for more details.
132133- The `nettools` package (ifconfig, arp, mii-tool, netstat, route) is not installed by default anymore. The suite is unmaintained and users should migrate to `iproute2` and `ethtool` instead.
134+135+- `sparkleshare` has been removed as it no longer builds and has been abandoned upstream.
+33
nixos/modules/hardware/kryoflux.nix
···000000000000000000000000000000000
···1+{
2+ config,
3+ lib,
4+ pkgs,
5+ ...
6+}:
7+8+let
9+ cfg = config.programs.kryoflux;
10+11+in
12+{
13+ options.programs.kryoflux = {
14+ enable = lib.mkOption {
15+ type = lib.types.bool;
16+ default = false;
17+ description = ''
18+ Enables kryoflux udev rules, ensures 'floppy' group exists. This is a
19+ prerequisite to using devices supported by kryoflux without being root,
20+ since kryoflux device descriptors will be owned by floppy through udev.
21+ '';
22+ };
23+ package = lib.mkPackageOption pkgs "kryoflux" { };
24+ };
25+26+ config = lib.mkIf cfg.enable {
27+ services.udev.packages = [ cfg.package ];
28+ environment.systemPackages = [ cfg.package ];
29+ users.groups.floppy = { };
30+ };
31+32+ meta.maintainers = with lib.maintainers; [ matthewcroughan ];
33+}
···1diff --git a/scripts/msmtpq/msmtpq b/scripts/msmtpq/msmtpq
2-index bcb384e..dbaf1b5 100755
3--- a/scripts/msmtpq/msmtpq
4+++ b/scripts/msmtpq/msmtpq
5-@@ -92,6 +92,8 @@ if [ ! -v MSMTPQ_LOG ] ; then
6- fi
7 fi
8- [ -d "$(dirname "$MSMTPQ_LOG")" ] || mkdir -p "$(dirname "$MSMTPQ_LOG")"
9-+
10+JOURNAL=@journal@
11- ## ======================================================================================
01213- ## msmtpq can use the following environment variables :
14-@@ -144,6 +146,7 @@ on_exit() { # unlock the queue on exit if the lock was
15 ## display msg to user, as well
16 ##
17 log() {
···19 local ARG RC PFX
20 PFX="$('date' +'%Y %d %b %H:%M:%S')"
21 # time stamp prefix - "2008 13 Mar 03:59:45 "
22-@@ -161,10 +164,19 @@ log() {
23 done
24 fi
25
···1diff --git a/scripts/msmtpq/msmtpq b/scripts/msmtpq/msmtpq
2+index 28d0754..3eaac58 100755
3--- a/scripts/msmtpq/msmtpq
4+++ b/scripts/msmtpq/msmtpq
5+@@ -182,6 +182,8 @@ if [ -n "$MSMTPQ_LOG" ] ; then
6+ unset msmptq_log_dir
7 fi
8+09+JOURNAL=@journal@
10++
11+ umask 077 # set secure permissions on created directories and files
1213+ declare -i CNT # a count of mail(s) currently in the queue
14+@@ -214,6 +216,7 @@ on_exit() { # unlock the queue on exit if the lock was
15 ## display msg to user, as well
16 ##
17 log() {
···19 local ARG RC PFX
20 PFX="$('date' +'%Y %d %b %H:%M:%S')"
21 # time stamp prefix - "2008 13 Mar 03:59:45 "
22+@@ -233,10 +236,19 @@ log() {
23 done
24 fi
25
···6566rustPlatform.buildRustPackage {
67 pname = "servo";
68- version = "0-unstable-2025-07-08";
6970 src = fetchFromGitHub {
71 owner = "servo";
72 repo = "servo";
73- rev = "c3f441d7abe7243a31150bf424babf0f1679ea88";
74- hash = "sha256-rFROwsU/x8LsD8vpCcmLyQMYCl9AQwgbv/kHk7JTa4c=";
75 # Breaks reproducibility depending on whether the picked commit
76 # has other ref-names or not, which may change over time, i.e. with
77 # "ref-names: HEAD -> main" as long this commit is the branch HEAD
···82 };
8384 useFetchCargoVendor = true;
85- cargoHash = "sha256-2J6ByE2kmoHBGWgwYU2FWgTt47cw+s8IPcm4ElRVWMc=";
8687 # set `HOME` to a temp dir for write access
88 # Fix invalid option errors during linking (https://github.com/mozilla/nixpkgs-mozilla/commit/c72ff151a3e25f14182569679ed4cd22ef352328)
···6566rustPlatform.buildRustPackage {
67 pname = "servo";
68+ version = "0-unstable-2025-07-13";
6970 src = fetchFromGitHub {
71 owner = "servo";
72 repo = "servo";
73+ rev = "93e5b672a78247205c431d5741952bdf23c3fcc2";
74+ hash = "sha256-0826hNZ45BXXNzdZKbyUW/CfwVRZmpYU1e6efaACh4o=";
75 # Breaks reproducibility depending on whether the picked commit
76 # has other ref-names or not, which may change over time, i.e. with
77 # "ref-names: HEAD -> main" as long this commit is the branch HEAD
···82 };
8384 useFetchCargoVendor = true;
85+ cargoHash = "sha256-uB5eTGiSq+DV7VwYoyLR2HH3DQpSV4xnP7C7iXZa7S0=";
8687 # set `HOME` to a temp dir for write access
88 # Fix invalid option errors during linking (https://github.com/mozilla/nixpkgs-mozilla/commit/c72ff151a3e25f14182569679ed4cd22ef352328)
···46 disabledTests = [
47 # Tests require openssh_wrapper which is outdated and not available
48 "test_repr_openssh"
00049 ];
5051 pythonImportsCheck = [ "proxmoxer" ];
···46 disabledTests = [
47 # Tests require openssh_wrapper which is outdated and not available
48 "test_repr_openssh"
49+50+ # Test fails randomly
51+ "test_timeout"
52 ];
5354 pythonImportsCheck = [ "proxmoxer" ];