Merge master into staging-next

This commit is contained in:
nixpkgs-ci[bot]
2025-11-02 18:05:03 +00:00
committed by GitHub
59 changed files with 1060 additions and 547 deletions
+2 -23
View File
@@ -63,28 +63,6 @@ jobs:
permission-members: read
permission-pull-requests: write
- name: Log current API rate limits (app-token)
if: ${{ steps.app-token.outputs.token }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: gh api /rate_limit | jq
- name: Requesting code owner reviews
if: steps.app-token.outputs.token
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPOSITORY: ${{ github.repository }}
NUMBER: ${{ github.event.number }}
# Don't do anything on draft PRs
DRY_MODE: ${{ github.event.pull_request.draft && '1' || '' }}
run: result/bin/request-code-owner-reviews.sh "$REPOSITORY" "$NUMBER" ci/OWNERS
- name: Log current API rate limits (app-token)
if: ${{ steps.app-token.outputs.token }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: gh api /rate_limit | jq
- name: Log current API rate limits (github.token)
env:
GH_TOKEN: ${{ github.token }}
@@ -149,7 +127,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: gh api /rate_limit | jq
- name: Requesting maintainer reviews
- name: Requesting reviews
if: ${{ steps.app-token.outputs.token }}
env:
GH_TOKEN: ${{ github.token }}
@@ -164,6 +142,7 @@ jobs:
# There appears to be no API to request reviews based on GitHub IDs
jq -r 'keys[]' comparison/maintainers.json \
| while read -r id; do gh api /user/"$id" --jq .login; done \
| cat comparison/owners.txt - \
| GH_TOKEN="$APP_GH_TOKEN" result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR"
- name: Log current API rate limits (app-token)
+4 -2
View File
@@ -43,8 +43,10 @@ These issues effectively list PRs the merge bot has interacted with.
To ensure security and a focused utility, the bot adheres to specific limitations:
- The PR targets `master`, `staging`, or `staging-next`.
- The PR only touches files located under `pkgs/by-name/*`.
- The PR is authored by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/) or a [committer][@NixOS/nixpkgs-committers].
- The PR only touches packages located under `pkgs/by-name/*`.
- The PR is either:
- authored by a [committer][@NixOS/nixpkgs-committers], or
- created by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).
- The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers].
- The user attempting to merge is a maintainer of all packages touched by the PR.
+40
View File
@@ -7,6 +7,7 @@
python3,
stdenvNoCC,
makeWrapper,
codeowners,
}:
let
python = python3.withPackages (ps: [
@@ -48,6 +49,7 @@ in
{
combinedDir,
touchedFilesJson,
ownersFile ? ../../OWNERS,
}:
let
# Usually we expect a derivation, but when evaluating in multiple separate steps, we pass
@@ -174,6 +176,7 @@ runCommand "compare"
nativeBuildInputs = map lib.getBin [
jq
cmp-stats
codeowners
];
maintainers = builtins.toJSON maintainers;
packages = builtins.toJSON packages;
@@ -222,6 +225,43 @@ runCommand "compare"
} >> $out/step-summary.md
fi
jq -r '.[]' "${touchedFilesJson}" > ./touched-files
readarray -t touchedFiles < ./touched-files
echo "This PR touches ''${#touchedFiles[@]} files"
# TODO: Move ci/OWNERS to Nix and produce owners.json instead of owners.txt.
touch "$out/owners.txt"
for file in "''${touchedFiles[@]}"; do
result=$(codeowners --file "${ownersFile}" "$file")
# Remove the file prefix and trim the surrounding spaces
read -r owners <<< "''${result#"$file"}"
if [[ "$owners" == "(unowned)" ]]; then
echo "File $file is unowned"
continue
fi
echo "File $file is owned by $owners"
# Split up multiple owners, separated by arbitrary amounts of spaces
IFS=" " read -r -a entries <<< "$owners"
for entry in "''${entries[@]}"; do
# GitHub technically also supports Emails as code owners,
# but we can't easily support that, so let's not
if [[ ! "$entry" =~ @(.*) ]]; then
echo -e "\e[33mCodeowner \"$entry\" for file $file is not valid: Must start with \"@\"\e[0m"
# Don't fail, because the PR for which this script runs can't fix it,
# it has to be fixed in the base branch
continue
fi
# The first regex match is everything after the @
entry=''${BASH_REMATCH[1]}
echo "$entry" >> "$out/owners.txt"
done
done
cp "$maintainersPath" "$out/maintainers.json"
cp "$packagesPath" "$out/packages.json"
''
+104 -57
View File
@@ -1,33 +1,15 @@
// Caching the list of committers saves API requests when running the bot on the schedule and
// processing many PRs at once.
let committers
async function runChecklist({ github, context, pull_request, maintainers }) {
const pull_number = pull_request.number
if (!committers) {
if (context.eventName === 'pull_request') {
// We have no chance of getting a token in the pull_request context with the right
// permissions to access the members endpoint below. Thus, we're pretending to have
// no committers. This is OK; because this is only for the Test workflow, not for
// real use.
committers = new Set()
} else {
committers = github
.paginate(github.rest.teams.listMembersInOrg, {
org: context.repo.owner,
team_slug: 'nixpkgs-committers',
per_page: 100,
})
.then((members) => new Set(members.map(({ id }) => id)))
}
}
const files = await github.paginate(github.rest.pulls.listFiles, {
...context.repo,
pull_number,
per_page: 100,
})
function runChecklist({
committers,
files,
pull_request,
log,
maintainers,
user,
userIsMaintainer,
}) {
const allByName = files.every(({ filename }) =>
filename.startsWith('pkgs/by-name/'),
)
const packages = files
.filter(({ filename }) => filename.startsWith('pkgs/by-name/'))
@@ -45,19 +27,39 @@ async function runChecklist({ github, context, pull_request, maintainers }) {
'staging',
'staging-next',
].includes(pull_request.base.ref),
'PR touches only files in `pkgs/by-name/`.': files.every(({ filename }) =>
filename.startsWith('pkgs/by-name/'),
),
'PR authored by r-ryantm or committer.':
pull_request.user.login === 'r-ryantm' ||
(await committers).has(pull_request.user.id),
'PR has maintainers eligible for merge.': eligible.size > 0,
'PR touches only packages in `pkgs/by-name/`.': allByName,
'PR is at least one of:': {
'Authored by a committer.': committers.has(pull_request.user.id),
'Created by r-ryantm.': pull_request.user.login === 'r-ryantm',
},
}
if (user) {
checklist[
`${user.login} is a member of [@NixOS/nixpkgs-maintainers](https://github.com/orgs/NixOS/teams/nixpkgs-maintainers).`
] = userIsMaintainer
if (allByName) {
// We can only determine the below, if all packages are in by-name, since
// we can't reliably relate changed files to packages outside by-name.
checklist[`${user.login} is a maintainer of all touched packages.`] =
eligible.has(user.id)
}
} else {
// This is only used when no user is passed, i.e. for labeling.
checklist['PR has maintainers eligible to merge.'] = eligible.size > 0
}
const result = Object.values(checklist).every((v) =>
typeof v === 'boolean' ? v : Object.values(v).some(Boolean),
)
log('checklist', JSON.stringify(checklist))
log('eligible', JSON.stringify(Array.from(eligible)))
log('result', result)
return {
checklist,
eligible,
result: Object.values(checklist).every(Boolean),
result,
}
}
@@ -86,6 +88,10 @@ async function handleMergeComment({ github, body, node_id, reaction }) {
)
}
// Caching the list of team members saves API requests when running the bot on the schedule and
// processing many PRs at once.
const members = {}
async function handleMerge({
github,
context,
@@ -98,15 +104,34 @@ async function handleMerge({
}) {
const pull_number = pull_request.number
const { checklist, eligible, result } = await runChecklist({
github,
context,
pull_request,
maintainers,
function getTeamMembers(team_slug) {
if (context.eventName === 'pull_request') {
// We have no chance of getting a token in the pull_request context with the right
// permissions to access the members endpoint below. Thus, we're pretending to have
// no members. This is OK; because this is only for the Test workflow, not for
// real use.
return new Set()
}
if (!members[team_slug]) {
members[team_slug] = github
.paginate(github.rest.teams.listMembersInOrg, {
org: context.repo.owner,
team_slug,
per_page: 100,
})
.then((members) => new Set(members.map(({ id }) => id)))
}
return members[team_slug]
}
const committers = await getTeamMembers('nixpkgs-committers')
const files = await github.paginate(github.rest.pulls.listFiles, {
...context.repo,
pull_number,
per_page: 100,
})
log('checklist', JSON.stringify(checklist))
log('eligible', JSON.stringify(Array.from(eligible)))
log('result', result)
// Only look through comments *after* the latest (force) push.
const latestChange = events.findLast(({ event }) =>
@@ -158,6 +183,7 @@ async function handleMerge({
log('Auto Merge failed', e.response.errors[0].message)
}
// TODO: Observe whether the below is true and whether manual enqueue is actually needed.
// Auto-merge doesn't work if the target branch has already run all CI, in which
// case the PR must be enqueued explicitly.
// We now have merge queues enabled on all development branches, thus don't need a
@@ -217,23 +243,36 @@ async function handleMerge({
}
}
const canUseMergeBot = await isMaintainer(comment.user.login)
const isEligible = eligible.has(comment.user.id)
const canMerge = result && canUseMergeBot && isEligible
const { result, checklist } = runChecklist({
committers,
files,
pull_request,
log,
maintainers,
user: comment.user,
userIsMaintainer: await isMaintainer(comment.user.login),
})
const body = [
`<!-- comment: ${comment.node_id} -->`,
`@${comment.user.login} wants to merge this PR.`,
'',
'Requirements to merge this PR:',
...Object.entries(checklist).map(
([msg, res]) => `- :${res ? 'white_check_mark' : 'x'}: ${msg}`,
'Requirements to merge this PR with `@NixOS/nixpkgs-merge-bot merge`:',
...Object.entries(checklist).flatMap(([msg, res]) =>
typeof res === 'boolean'
? `- :${res ? 'white_check_mark' : 'x'}: ${msg}`
: [
`- :${Object.values(res).some(Boolean) ? 'white_check_mark' : 'x'}: ${msg}`,
...Object.entries(res).map(
([msg, res]) =>
` - ${res ? ':white_check_mark:' : ':white_large_square:'} ${msg}`,
),
],
),
`- :${canUseMergeBot ? 'white_check_mark' : 'x'}: ${comment.user.login} can use the merge bot.`,
`- :${isEligible ? 'white_check_mark' : 'x'}: ${comment.user.login} is eligible to merge changes to the touched packages.`,
'',
]
if (canMerge) {
if (result) {
await react('ROCKET')
try {
body.push(`:heavy_check_mark: ${await merge()} (#306934)`)
@@ -257,9 +296,17 @@ async function handleMerge({
})
}
if (canMerge) break
if (result) break
}
const { result } = runChecklist({
committers,
files,
pull_request,
log,
maintainers,
})
// Returns a boolean, which indicates whether the PR is merge-bot eligible in principle.
// This is used to set the respective label in bot.js.
return result
-8
View File
@@ -3,20 +3,15 @@
stdenvNoCC,
makeWrapper,
coreutils,
codeowners,
jq,
curl,
github-cli,
gitMinimal,
}:
stdenvNoCC.mkDerivation {
name = "request-reviews";
src = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./get-code-owners.sh
./request-reviewers.sh
./request-code-owner-reviews.sh
];
};
nativeBuildInputs = [ makeWrapper ];
@@ -29,11 +24,8 @@ stdenvNoCC.mkDerivation {
--set PATH ${
lib.makeBinPath [
coreutils
codeowners
jq
curl
github-cli
gitMinimal
]
}
done
-97
View File
@@ -1,97 +0,0 @@
#!/usr/bin/env bash
# Get the code owners of the files changed by a PR, returning one username per line
set -euo pipefail
log() {
echo "$@" >&2
}
if (( "$#" < 4 )); then
log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REF HEAD_REF"
exit 1
fi
gitRepo=$1
ownersFile=$2
baseRef=$3
headRef=$4
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
git -C "$gitRepo" diff --name-only --merge-base "$baseRef" "$headRef" > "$tmp/touched-files"
readarray -t touchedFiles < "$tmp/touched-files"
log "This PR touches ${#touchedFiles[@]} files"
# Get the owners file from the base, because we don't want to allow PRs to
# remove code owners to avoid pinging them
git -C "$gitRepo" show "$baseRef":"$ownersFile" > "$tmp"/codeowners
# Associative array with the user as the key for easy de-duplication
# Make sure to always lowercase keys to avoid duplicates with different casings
declare -A users=()
for file in "${touchedFiles[@]}"; do
result=$(codeowners --file "$tmp"/codeowners "$file")
# Remove the file prefix and trim the surrounding spaces
read -r owners <<< "${result#"$file"}"
if [[ "$owners" == "(unowned)" ]]; then
log "File $file is unowned"
continue
fi
log "File $file is owned by $owners"
# Split up multiple owners, separated by arbitrary amounts of spaces
IFS=" " read -r -a entries <<< "$owners"
for entry in "${entries[@]}"; do
# GitHub technically also supports Emails as code owners,
# but we can't easily support that, so let's not
if [[ ! "$entry" =~ @(.*) ]]; then
warn -e "\e[33mCodeowner \"$entry\" for file $file is not valid: Must start with \"@\"\e[0m" >&2
# Don't fail, because the PR for which this script runs can't fix it,
# it has to be fixed in the base branch
continue
fi
# The first regex match is everything after the @
entry=${BASH_REMATCH[1]}
if [[ "$entry" =~ (.*)/(.*) ]]; then
# Teams look like $org/$team
org=${BASH_REMATCH[1]}
team=${BASH_REMATCH[2]}
# Instead of requesting a review from the team itself,
# we request reviews from the individual users.
# This is because once somebody from a team reviewed the PR,
# the API doesn't expose that the team was already requested for a review,
# so we wouldn't be able to avoid rerequesting reviews
# without saving some some extra state somewhere
# We could also consider implementing a more advanced heuristic
# in the future that e.g. only pings one team member,
# but escalates to somebody else if that member doesn't respond in time.
gh api \
--cache=1h \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/$org/teams/$team/members" \
--jq '.[].login' > "$tmp/team-members"
readarray -t members < "$tmp/team-members"
log "Team $entry has these members: ${members[*]}"
for user in "${members[@]}"; do
users[${user,,}]=
done
else
# Everything else is a user
users[${entry,,}]=
fi
done
done
printf "%s\n" "${!users[@]}"
@@ -1,60 +0,0 @@
#!/usr/bin/env bash
# Requests reviews for a PR
set -euo pipefail
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
SCRIPT_DIR=$(dirname "$0")
log() {
echo "$@" >&2
}
if (( $# < 3 )); then
log "Usage: $0 GITHUB_REPO PR_NUMBER OWNERS_FILE"
exit 1
fi
baseRepo=$1
prNumber=$2
ownersFile=$3
log "Fetching PR info"
prInfo=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/$baseRepo/pulls/$prNumber")
baseBranch=$(jq -r .base.ref <<< "$prInfo")
log "Base branch: $baseBranch"
prRepo=$(jq -r .head.repo.full_name <<< "$prInfo")
log "PR repo: $prRepo"
prBranch=$(jq -r .head.ref <<< "$prInfo")
log "PR branch: $prBranch"
prAuthor=$(jq -r .user.login <<< "$prInfo")
log "PR author: $prAuthor"
extraArgs=()
if pwdRepo=$(git rev-parse --show-toplevel 2>/dev/null); then
# Speedup for local runs
extraArgs+=(--reference-if-able "$pwdRepo")
fi
log "Fetching Nixpkgs commit history"
# We only need the commit history, not the contents, so we can do a tree-less clone using tree:0
# https://github.blog/open-source/git/get-up-to-speed-with-partial-clone-and-shallow-clone/#user-content-quick-summary
git clone --bare --filter=tree:0 --no-tags --origin upstream "${extraArgs[@]}" https://github.com/"$baseRepo".git "$tmp"/nixpkgs.git
log "Fetching the PR commit history"
# Fetch the PR
git -C "$tmp/nixpkgs.git" remote add fork https://github.com/"$prRepo".git
# This remote config is the same as --filter=tree:0 when cloning
git -C "$tmp/nixpkgs.git" config remote.fork.partialclonefilter tree:0
git -C "$tmp/nixpkgs.git" config remote.fork.promisor true
git -C "$tmp/nixpkgs.git" fetch --no-tags fork "$prBranch"
headRef=$(git -C "$tmp/nixpkgs.git" rev-parse refs/remotes/fork/"$prBranch")
log "Requesting reviews from code owners"
"$SCRIPT_DIR"/get-code-owners.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseBranch" "$headRef" | \
"$SCRIPT_DIR"/request-reviewers.sh "$baseRepo" "$prNumber" "$prAuthor"
+34 -2
View File
@@ -33,9 +33,41 @@ prAuthor=$3
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
# Associative array with the user as the key for easy de-duplication
# Make sure to always lowercase keys to avoid duplicates with different casings
declare -A users=()
while read -r handle && [[ -n "$handle" ]]; do
users[${handle,,}]=
if [[ "$handle" =~ (.*)/(.*) ]]; then
# Teams look like $org/$team
org=${BASH_REMATCH[1]}
team=${BASH_REMATCH[2]}
# Instead of requesting a review from the team itself,
# we request reviews from the individual users.
# This is because once somebody from a team reviewed the PR,
# the API doesn't expose that the team was already requested for a review,
# so we wouldn't be able to avoid rerequesting reviews
# without saving some some extra state somewhere
# We could also consider implementing a more advanced heuristic
# in the future that e.g. only pings one team member,
# but escalates to somebody else if that member doesn't respond in time.
gh api \
--cache=1h \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/$org/teams/$team/members" \
--jq '.[].login' > "$tmp/team-members"
readarray -t members < "$tmp/team-members"
log "Team $handle has these members: ${members[*]}"
for user in "${members[@]}"; do
users[${user,,}]=
done
else
# Everything else is a user
users[${handle,,}]=
fi
done
# Cannot request a review from the author
@@ -68,7 +100,7 @@ for user in "${!users[@]}"; do
fi
done
if [[ "${#users[@]}" -gt 10 ]]; then
if [[ "${#users[@]}" -gt 15 ]]; then
log "Too many reviewers (${!users[*]}), skipping review requests"
exit 0
fi
+1 -1
View File
@@ -7991,7 +7991,7 @@
};
euxane = {
name = "euxane";
email = "r9uhdi.nixpkgs@euxane.net";
email = "r9uhdi.nixpkgs@euxane.eu";
github = "pacien";
githubId = 1449319;
};
@@ -100,6 +100,8 @@
- [crowdsec](https://www.crowdsec.net/), a free, open-source and collaborative IPS. Available as [services.crowdsec](#opt-services.crowdsec.enable).
- [crowdsec-firewall-bouncer](https://www.crowdsec.net/), the CrowdSec Remediation Component for fetching new and old decisions from a CrowdSec API and adding them to a blocklist used by supported firewalls. Available as [services.crowdsec-firewall-bouncer](#opt-services.crowdsec-firewall-bouncer.enable).
- [tsidp](https://github.com/tailscale/tsidp), a simple OIDC / OAuth Identity Provider (IdP) server for your tailnet. Available as [services.tsidp](#opt-services.tsidp.enable).
- [Newt](https://github.com/fosrl/newt), a fully user space WireGuard tunnel client and TCP/UDP proxy, designed to securely expose private resources controlled by Pangolin. Available as [services.newt](options.html#opt-services.newt.enable).
+1
View File
@@ -1460,6 +1460,7 @@
./services/security/certmgr.nix
./services/security/cfssl.nix
./services/security/clamav.nix
./services/security/crowdsec-firewall-bouncer.nix
./services/security/crowdsec.nix
./services/security/e-imzo.nix
./services/security/endlessh-go.nix
@@ -0,0 +1,390 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.crowdsec-firewall-bouncer;
format = pkgs.formats.yaml { };
in
{
options.services.crowdsec-firewall-bouncer =
let
inherit (lib)
types
mkOption
mkEnableOption
mkPackageOption
;
in
{
enable = mkEnableOption "CrowdSec Firewall Bouncer";
package = mkPackageOption pkgs "crowdsec-firewall-bouncer" { };
createRulesets = mkOption {
type = types.bool;
description = ''
Whether to have the module create the appropriate firewall configuration
based on the bouncer settings.
You may disable this option to manually configure it.
'';
default = true;
};
registerBouncer = {
enable = mkOption {
type = types.bool;
description = ''
Whether to automatically register the bouncer to the locally running
`crowdsec` service.
When authenticating to an external CrowdSec API, you may use the
[](#opt-services.crowdsec-firewall-bouncer.secrets.apiKeyPath) option
instead.
'';
default = config.services.crowdsec.enable;
defaultText = lib.literalExpression ''config.services.crowdsec.enable'';
};
bouncerName = mkOption {
type = types.nonEmptyStr;
description = "Name to register the bouncer as to the CrowdSec API";
default = "crowdsec-firewall-bouncer";
};
};
secrets = {
apiKeyPath = mkOption {
type = types.nullOr types.path;
description = ''
Path to the API key to authenticate with a local CrowdSec API.
You need to call `cscli bouncers add <bouncer-name>` to register
the bouncer and get this API key.
When authenticating to the locally running `crowdsec` service, you may use the
[](#opt-services.crowdsec-firewall-bouncer.registerBouncer.enable) option instead.
'';
default = null;
};
};
settings = mkOption {
description = ''
Settings for the main CrowdSec Firewall Bouncer.
Refer to the defaults at <https://github.com/crowdsecurity/cs-firewall-bouncer/blob/main/config/crowdsec-firewall-bouncer.yaml>.
'';
default = { };
type = types.submodule {
freeformType = format.type;
options = {
mode = mkOption {
type = types.str;
description = "Firewall mode to use.";
default = if config.networking.nftables.enable then "nftables" else "iptables";
defaultText = lib.literalExpression ''if config.networking.nftables.enable then "nftables" else "iptables"'';
};
api_url = mkOption {
type = types.str;
description = "URL of the local API.";
example = "http://127.0.0.1:8080";
default = "http://${config.services.crowdsec.settings.general.api.server.listen_uri}";
defaultText = lib.literalExpression ''http://$\{config.services.crowdsec.settings.general.api.server.listen_uri}'';
};
api_key = mkOption {
type = types.nullOr types.str;
description = ''
API key to authenticate with a local crowdsec API.
You need to call `cscli bouncers add <bouncer-name>` to register
the bouncer and get this API key.
Setting this option will store this secret in the Nix store.
Instead, you should set the `services.crowdsec-firewall-bouncer.secrets.apiKeyPath`
option, which will read the value at runtime.
'';
default = null;
};
};
};
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion =
cfg.registerBouncer.enable || (cfg.secrets.apiKeyPath != null) || (cfg.settings.api_key != null);
message = ''
An API key must be set for the bouncer to be able to authenticate to a local crowdsec API.
See the `registerBouncer.enable` and `secrets.apiKeyPath` options of
`services.crowdsec-firewall-bouncer` for more information.
'';
}
{
assertion = !(cfg.registerBouncer.enable && (cfg.secrets.apiKeyPath != null));
message = ''
The `registerBouncer.enable` and `secrets.apiKeyPath` options of
`services.crowdsec-firewall-bouncer` are mutually exclusive.
'';
}
{
assertion = !(cfg.registerBouncer.enable && !config.services.crowdsec.enable);
message = ''
The `services.crowdsec-firewall-bouncer.registerBouncer.enable` option
requires the `crowdsec` service to be enabled.
'';
}
{
assertion = !(cfg.settings.mode == "ipset" && cfg.createRulesets);
message = ''
The crowdsec-firewall-bouncer module is currently not able to configure the firewall in "ipset" mode.
Either set the `services.crowdsec-firewall-bouncer.settings.mode` to "iptables" to leave the bouncer
manage the firewall configuration, or disable the `services.crowdsec-firewall-bouncer.createRulesets`
option and manually configure your firewall.
'';
}
];
# Default settings
services.crowdsec-firewall-bouncer.settings = {
update_frequency = lib.mkDefault "10s";
log_mode = lib.mkDefault "stdout";
log_level = lib.mkDefault "info";
# iptables-specific config
blacklists_ipv4 = lib.mkDefault "crowdsec-blacklists";
blacklists_ipv6 = lib.mkDefault "crowdsec6-blacklists";
iptables_chains = lib.mkDefault [ "INPUT" ];
# nftables-specific config
nftables = {
ipv4 = {
enabled = lib.mkDefault true;
set-only = lib.mkDefault true;
table = lib.mkDefault "crowdsec";
chain = lib.mkDefault "crowdsec-chain";
};
ipv6 = {
enabled = lib.mkDefault true;
set-only = lib.mkDefault true;
table = lib.mkDefault "crowdsec6";
chain = lib.mkDefault "crowdsec6-chain";
};
};
};
# Use a placeholder for the api_key if it is to be read from a file at runtime
services.crowdsec-firewall-bouncer.settings.api_key = lib.mkIf (
cfg.registerBouncer.enable || (cfg.secrets.apiKeyPath != null)
) "@API_KEY_FILE@";
networking.nftables.tables = lib.mkIf (cfg.settings.mode == "nftables") {
"${cfg.settings.nftables.ipv4.table}" =
lib.mkIf
(cfg.createRulesets && cfg.settings.nftables.ipv4.enabled && cfg.settings.nftables.ipv4.set-only)
{
family = "ip";
content = ''
set crowdsec-blacklists {
type ipv4_addr
flags timeout
}
chain ${cfg.settings.nftables.ipv4.chain} {
type filter hook input priority filter; policy accept;
ip saddr @crowdsec-blacklists drop
}
'';
};
"${cfg.settings.nftables.ipv6.table}" =
lib.mkIf
(cfg.createRulesets && cfg.settings.nftables.ipv6.enabled && cfg.settings.nftables.ipv6.set-only)
{
family = "ip6";
content = ''
set crowdsec6-blacklists {
type ipv6_addr
flags timeout
}
chain ${cfg.settings.nftables.ipv6.chain} {
type filter hook input priority filter; policy accept;
ip6 saddr @crowdsec6-blacklists drop
}
'';
};
};
systemd.services =
let
apiKeyFile = "/var/lib/crowdsec-firewall-bouncer-register/api-key.cred";
in
{
crowdsec-firewall-bouncer-register = lib.mkIf cfg.registerBouncer.enable rec {
description = "Register the CrowdSec Firewall Bouncer to the local CrowdSec service";
wantedBy = [ "multi-user.target" ];
after = [ "crowdsec.service" ];
wants = after;
script = ''
cscli=/run/current-system/sw/bin/cscli
if $cscli bouncers list --output json | ${lib.getExe pkgs.jq} -e -- ${lib.escapeShellArg "any(.[]; .name == \"${cfg.registerBouncer.bouncerName}\")"} >/dev/null; then
# Bouncer already registered. Verify the API key is still present
if [ ! -f ${apiKeyFile} ]; then
echo "Bouncer registered but API key is not present"
exit 1
fi
else
# Bouncer not registered
# Remove any previously saved API key
rm -f '${apiKeyFile}'
# Register the bouncer and save the new API key
if ! $cscli bouncers add --output raw -- ${lib.escapeShellArg cfg.registerBouncer.bouncerName} >${apiKeyFile}; then
# Failed to register the bouncer
rm ${apiKeyFile}
exit 1
fi
fi
'';
serviceConfig = {
Type = "oneshot";
# Run as crowdsec user to be able to use cscli
User = config.services.crowdsec.user;
Group = config.services.crowdsec.group;
StateDirectory = "crowdsec-firewall-bouncer-register";
ReadWritePaths = [
# Needs write permissions to add the bouncer
"/var/lib/crowdsec"
];
DynamicUser = true;
LockPersonality = true;
PrivateDevices = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
RestrictAddressFamilies = "none";
CapabilityBoundingSet = [ "" ];
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0077";
};
};
crowdsec-firewall-bouncer =
let
runtime-dir-name = "crowdsec-firewall-bouncer";
final-config-file = "/run/${runtime-dir-name}/config.yaml";
generateConfig = pkgs.writeShellScript "crowdsec-firewall-bouncer-config" ''
set -euo pipefail
umask 077
# Copy the template to the final location
cp ${format.generate "crowdsec-firewall-bouncer-config-template.yml" cfg.settings} ${final-config-file}
chmod 0600 ${final-config-file}
# Replace the api_key placeholder with the secret
${lib.getExe pkgs.replace-secret} '@API_KEY_FILE@' "$CREDENTIALS_DIRECTORY/API_KEY_FILE" ${final-config-file}
'';
in
rec {
description = "CrowdSec Firewall Bouncer";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ] ++ (lib.optional config.services.crowdsec.enable "crowdsec.service");
wants = after;
requires = lib.optional cfg.registerBouncer.enable "crowdsec-firewall-bouncer-register.service";
# When using iptables/ipset modes, the bouncer calls external binaries so they must be added to the path.
# For nftables mode, it does not depend on external binaries.
path = lib.optionals ((cfg.settings.mode == "iptables") || (cfg.settings.mode == "ipset")) [
pkgs.iptables
pkgs.ipset
];
serviceConfig = rec {
Type = "notify";
ExecStartPre = [
generateConfig
"${lib.getExe cfg.package} -c ${final-config-file} -t"
];
ExecStart = [
"${lib.getExe cfg.package} -c ${final-config-file}"
];
# Same as upstream
LimitNOFILE = 65536;
KillMode = "mixed";
# Load the api_key secret to be able to use it when generating the final config
LoadCredential =
if (cfg.registerBouncer.enable) then
"API_KEY_FILE:${apiKeyFile}"
else if (cfg.secrets.apiKeyPath != null) then
"API_KEY_FILE:${cfg.secrets.apiKeyPath}"
else
null;
DynamicUser = true;
RuntimeDirectory = runtime-dir-name;
LockPersonality = true;
PrivateDevices = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
RestrictAddressFamilies = [
"AF_NETLINK"
"AF_UNIX"
"AF_INET"
"AF_INET6"
];
AmbientCapabilities = [
# Needed to be able to manipulate the rulesets
"CAP_NET_ADMIN"
];
CapabilityBoundingSet = AmbientCapabilities;
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0077";
};
};
};
};
meta = {
maintainers = with lib.maintainers; [ nicomem ];
};
}
+13 -14
View File
@@ -2,6 +2,7 @@
lib,
pkgs,
config,
utils,
...
}:
let
@@ -16,7 +17,6 @@ let
;
cfg = config.services.actual;
configFile = formatType.generate "config.json" cfg.settings;
dataDir = "/var/lib/actual";
formatType = pkgs.formats.json { };
@@ -32,19 +32,12 @@ in
description = "Whether to open the firewall for the specified port.";
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Environment file for specifying additional settings such as secrets.
See <https://actualbudget.org/docs/config/oauth-auth#environment-variables>.
'';
};
settings = mkOption {
default = { };
description = "Server settings, refer to [the documentation](https://actualbudget.org/docs/config/) for available options.";
description = ''
Server settings, refer to [the documentation](https://actualbudget.org/docs/config/) for available options.
You can specify secret values in this configuration by setting `somevalue._secret = "/path/to/file"` instead of setting `somevalue` directly.
'';
type = types.submodule {
freeformType = formatType.type;
@@ -78,15 +71,21 @@ in
description = "Actual server, a local-first personal finance app";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment.ACTUAL_CONFIG_PATH = configFile;
environment.ACTUAL_CONFIG_PATH = "/run/actual/config.json";
preStart = ''
# Generate config including secret values.
${utils.genJqSecretsReplacementSnippet cfg.settings "/run/actual/config.json"}
'';
serviceConfig = {
ExecStart = getExe cfg.package;
DynamicUser = true;
User = "actual";
Group = "actual";
StateDirectory = "actual";
RuntimeDirectory = "actual";
WorkingDirectory = dataDir;
EnvironmentFile = cfg.environmentFile;
LimitNOFILE = "1048576";
PrivateTmp = true;
PrivateDevices = true;
+15 -2
View File
@@ -21,6 +21,7 @@
environment.systemPackages = [ pkgs.xfce.xfce4-whiskermenu-plugin ];
programs.thunar.plugins = [ pkgs.xfce.thunar-archive-plugin ];
programs.ydotool.enable = true;
};
enableOCR = true;
@@ -44,8 +45,9 @@
with subtest("Check if Xfce components actually start"):
machine.wait_for_window("xfce4-panel")
machine.wait_for_window("Desktop")
for i in ["xfwm4", "xfsettingsd", "xfdesktop", "xfce4-screensaver", "xfce4-notifyd", "xfconfd"]:
machine.wait_until_succeeds(f"pgrep -f {i}")
for i in ["xfwm4", "xfsettingsd", "xfdesktop", "xfce4-notifyd", "xfconfd"]:
machine.wait_until_succeeds(f"pgrep {i}")
machine.wait_until_succeeds("pgrep -xf xfce4-screensaver")
with subtest("Open whiskermenu"):
machine.succeed("su - ${user.name} -c 'DISPLAY=:0 ${bus} xfconf-query -c xfce4-panel -p /plugins/plugin-1 -t string -s whiskermenu -n >&2 &'")
@@ -63,6 +65,17 @@
machine.succeed("su - ${user.name} -c 'DISPLAY=:0 xfce4-terminal >&2 &'")
machine.wait_for_window("Terminal")
with subtest("Lock the screen"):
machine.succeed("su - ${user.name} -c '${bus} xflock4 >&2 &'")
machine.wait_until_succeeds("su - ${user.name} -c '${bus} xfce4-screensaver-command -q' | grep 'The screensaver is active'")
machine.sleep(5)
machine.succeed("ydotool click 0xC0")
machine.wait_for_text("${user.description}|Unlock")
machine.screenshot("screensaver")
machine.send_chars("${user.password}\n", delay=0.2)
machine.wait_until_succeeds("su - ${user.name} -c '${bus} xfce4-screensaver-command -q' | grep 'The screensaver is inactive'")
machine.sleep(2)
with subtest("Open Thunar"):
machine.succeed("su - ${user.name} -c 'DISPLAY=:0 thunar >&2 &'")
machine.wait_for_window("Thunar")
@@ -10,6 +10,7 @@
wrapQtAppsHook ? null,
boost,
libevent,
libsodium,
zeromq,
zlib,
db48,
@@ -67,6 +68,7 @@ stdenv.mkDerivation (finalAttrs: {
buildInputs = [
boost
libevent
libsodium
zeromq
zlib
]
@@ -949,13 +949,13 @@
"vendorHash": "sha256-OAd8SeTqTrH0kMoM2LsK3vM2PI23b3gl57FaJYM9hM0="
},
"newrelic_newrelic": {
"hash": "sha256-/vHE+Eys773WyYMDe7xG3p0pgKvRc9U73s4jSDijNxY=",
"hash": "sha256-1OpvSayWq194591u/z9oHz80ZmPA9fSZpKSBwDHL/tk=",
"homepage": "https://registry.terraform.io/providers/newrelic/newrelic",
"owner": "newrelic",
"repo": "terraform-provider-newrelic",
"rev": "v3.73.0",
"rev": "v3.74.0",
"spdx": "MPL-2.0",
"vendorHash": "sha256-45psSf69IetY0o8LjBDEv2GnOxaOzaQcPCnV2YHPXGs="
"vendorHash": "sha256-7zUUV3cqVesItNnE/EcO5/l+nafV04JdoNkmTxnulio="
},
"ns1-terraform_ns1": {
"hash": "sha256-S0ji/gZsbMTgug7DwPODAcPx3IfRaw1JHYPJ6V+tqeM=",
@@ -21,13 +21,13 @@
mkDerivation rec {
pname = "anilibria-winmaclinux";
version = "2.2.31";
version = "2.2.32";
src = fetchFromGitHub {
owner = "anilibria";
repo = "anilibria-winmaclinux";
rev = version;
hash = "sha256-czLEYPz+5vXHisXexzRXLhwN4onka31hn69F4MaSnCs=";
hash = "sha256-Wxzv1iLJ+OWw+g6ndBX36AR2v9cSu2uZysegz97+XaM=";
};
sourceRoot = "${src.name}/src";
+4 -4
View File
@@ -5,7 +5,7 @@
"packages": {
"": {
"dependencies": {
"@sourcegraph/amp": "^0.0.1761583653-gd8c2df"
"@sourcegraph/amp": "^0.0.1762056193-g37ad2e"
}
},
"node_modules/@napi-rs/keyring": {
@@ -228,9 +228,9 @@
}
},
"node_modules/@sourcegraph/amp": {
"version": "0.0.1761583653-gd8c2df",
"resolved": "https://registry.npmjs.org/@sourcegraph/amp/-/amp-0.0.1761583653-gd8c2df.tgz",
"integrity": "sha512-/sAPMVQkj3sLtuYfv4GAXRBfqrWPHcMXbeWXXqW0+i8GKMsrMIenawwkEzQdCoTH94eZYeS8JlBPde3YFsdDOA==",
"version": "0.0.1762056193-g37ad2e",
"resolved": "https://registry.npmjs.org/@sourcegraph/amp/-/amp-0.0.1762056193-g37ad2e.tgz",
"integrity": "sha512-dWhc7ajnw1QGCYwrOGwCbpyzedf5n2RoTCM97ibpzgpphDLCdyGTXh2XTC6mrxM2CNQLp5jJaWxvcDk9nM80Vg==",
"dependencies": {
"@napi-rs/keyring": "1.1.9"
},
+3 -3
View File
@@ -9,11 +9,11 @@
buildNpmPackage (finalAttrs: {
pname = "amp-cli";
version = "0.0.1761583653-gd8c2df";
version = "0.0.1762056193-g37ad2e";
src = fetchzip {
url = "https://registry.npmjs.org/@sourcegraph/amp/-/amp-${finalAttrs.version}.tgz";
hash = "sha256-Q6iBVtSIXoy6r+9/s3GefLq5c9SFRSQoBxUjBlg/wh8=";
hash = "sha256-so/nlX4N9qhNLsK0OllmpfiqzyEBtPrt7KD/MoAChGc=";
};
postPatch = ''
@@ -45,7 +45,7 @@ buildNpmPackage (finalAttrs: {
chmod +x bin/amp-wrapper.js
'';
npmDepsHash = "sha256-n8dRIJPTFFhS3aQQKKRdqYcEeHxfpU9XGbeV+2XAVeY=";
npmDepsHash = "sha256-xhN5XJs8E7yCRQWRPlH9iZyh5FocUjFMto5QweaV8aI=";
propagatedBuildInputs = [
ripgrep
+3 -3
View File
@@ -14,13 +14,13 @@
}:
let
pname = "backrest";
version = "1.9.2";
version = "1.10.1";
src = fetchFromGitHub {
owner = "garethgeorge";
repo = "backrest";
tag = "v${version}";
hash = "sha256-3lAWViC9K34R8la/z57kjGJmMmletGd8pJ1dDt+BeKQ=";
hash = "sha256-8WWs7XEVKAc/XmeL+dsw25azfLjUbHKp2MsB6Be14VE=";
};
frontend = stdenv.mkDerivation (finalAttrs: {
@@ -64,7 +64,7 @@ buildGoModule {
internal/resticinstaller/resticinstaller.go
'';
vendorHash = "sha256-oycV8JAJQF/PNc7mmYGzkZbpG8pMwxThmuys9e0+hcc=";
vendorHash = "sha256-cYqK/sddLI38K9bzCpnomcZOYbSRDBOEru4Y26rBLFw=";
nativeBuildInputs = [
gzip
+2 -2
View File
@@ -6,13 +6,13 @@
}:
buildGoModule rec {
pname = "bitrise";
version = "2.34.5";
version = "2.34.6";
src = fetchFromGitHub {
owner = "bitrise-io";
repo = "bitrise";
rev = "v${version}";
hash = "sha256-QsGF5lDnY55OGdFagGJfXcq9/2P6qzmoHx64ijOkRfo=";
hash = "sha256-wA+IknAOkVxTwBohw8D4suksENoWymqPJycbfx6cFYQ=";
};
# many tests rely on writable $HOME/.bitrise and require network access
+9 -9
View File
@@ -9,26 +9,26 @@ let
inherit (stdenv) hostPlatform;
sources = {
x86_64-linux = fetchurl {
url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/linux/x64/agent-cli-package.tar.gz";
hash = "sha256-bblnHWrPXJ9UmStfjUis1jLYLyawRchF0+UBMmPHy7M=";
url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/linux/x64/agent-cli-package.tar.gz";
hash = "sha256-mZ0T7rrKzwvaNUbrHBy3XO04vZSO6RQ4RmJmrdfaoJA=";
};
aarch64-linux = fetchurl {
url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/linux/arm64/agent-cli-package.tar.gz";
hash = "sha256-MnL1TLI7ggi9qaicUN//8o3EJoCPd0gF9KKfekIhUM0=";
url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/linux/arm64/agent-cli-package.tar.gz";
hash = "sha256-bchHYPQ0O/0YWiPdj3wnq43p/fKFoP4KXpeSVWpLYpE=";
};
x86_64-darwin = fetchurl {
url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/darwin/x64/agent-cli-package.tar.gz";
hash = "sha256-UEQyHEopNKf5uDUlZVzTESXVi8e2wHp83cD01diAISY=";
url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/darwin/x64/agent-cli-package.tar.gz";
hash = "sha256-PWx5QAs84gWNOHYZL20uFnW+m4rApRT6g4LtabjL+lw=";
};
aarch64-darwin = fetchurl {
url = "https://downloads.cursor.com/lab/2025.10.22-f894c20/darwin/arm64/agent-cli-package.tar.gz";
hash = "sha256-18u5K/4Mc9+R32umaBWD5chgMoatkd/ZSMCiPElmPJU=";
url = "https://downloads.cursor.com/lab/2025.10.28-0a91dc2/darwin/arm64/agent-cli-package.tar.gz";
hash = "sha256-VW76Lx2VKspiGkphp74ib4+F5FCdu8793f+xvD67OpM=";
};
};
in
stdenv.mkDerivation {
pname = "cursor-cli";
version = "0-unstable-2025-10-22";
version = "0-unstable-2025-10-28";
src = sources.${hostPlatform.system};
@@ -8,16 +8,16 @@
buildGoModule rec {
pname = "docker-language-server";
version = "0.16.0";
version = "0.20.1";
src = fetchFromGitHub {
owner = "docker";
repo = "docker-language-server";
tag = "v${version}";
hash = "sha256-P3DwlCjQllFtf05ssXYNraQFGEEzChSE5eJvcODdF6Q=";
hash = "sha256-OSAySCTK2temrVxmkRnrl5YWVbmkp8DRlXFVxTzEW3Q=";
};
vendorHash = "sha256-xvRHxi7aem88mrmdAmSyRNtBUSZD4rjUut2VjPeoejg=";
vendorHash = "sha256-ztA+/4l180UKTKrsqTyysDcD4oQSDgnBYUaiKDF6LvI=";
nativeCheckInputs = [
docker
+1 -1
View File
@@ -12,7 +12,7 @@ buildGoModule {
owner = "freifunk-darmstadt";
repo = "fastd-exporter";
rev = "374e4334af6661f4c91a3e83bf7ce071a2a72eca";
sha256 = "sha256-0oU4+9G19XP5qtGdcfMz08T04hjcoXX/O+FkaUPxzXE=";
hash = "sha256-0oU4+9G19XP5qtGdcfMz08T04hjcoXX/O+FkaUPxzXE=";
};
vendorHash = "sha256-r0W64dct6XWa9sIrzy0UdyoMw+kAq73Qc/QchmsYZkY=";
@@ -0,0 +1,27 @@
{
pname,
version,
src,
passthru,
meta,
stdenvNoCC,
}:
stdenvNoCC.mkDerivation {
inherit
pname
version
src
passthru
meta
;
installPhase = ''
mkdir -p $out/Applications
cp -R Fastmail.app $out/Applications/
'';
dontBuild = true;
# Fastmail is notarized
dontFixup = true;
}
@@ -0,0 +1,84 @@
{
pname,
version,
src,
passthru,
meta,
lib,
stdenvNoCC,
appimageTools,
asar,
autoPatchelfHook,
makeWrapper,
electron,
libXScrnSaver,
libXtst,
libappindicator,
libgcc,
musl,
vips,
}:
let
appimageContents = appimageTools.extract { inherit pname version src; };
in
stdenvNoCC.mkDerivation (finalAttrs: {
inherit pname version passthru;
dontUnpack = true;
dontBuild = true;
strictDeps = true;
nativeBuildInputs = [
asar
autoPatchelfHook
makeWrapper
];
buildInputs = [
libgcc
musl
vips
];
libPath = lib.makeLibraryPath [
libXScrnSaver
libXtst
libappindicator
];
installPhase = ''
runHook preInstall
mkdir -p "$out/opt"
cp -r --no-preserve=mode "${appimageContents}/resources" "$out/opt/fastmail"
asar extract "$out/opt/fastmail/app.asar" "$out/opt/fastmail/app.asar.unpacked"
rm "$out/opt/fastmail/app.asar"
install -D "${appimageContents}/production.desktop" "$out/share/applications/fastmail.desktop"
substituteInPlace "$out/share/applications/fastmail.desktop" \
--replace-fail "Exec=AppRun --no-sandbox %U" "Exec=fastmail" \
--replace-fail "Icon=production" "Icon=fastmail" \
for res in 16 24 32 48 64 128 256 512 1024; do
resdir="''${res}x''${res}"
mkdir -p "$out/share/icons/hicolor/$resdir/apps"
cp -r --no-preserve=mode \
"${appimageContents}/usr/share/icons/hicolor/$resdir/apps/production.png" \
"$out/share/icons/hicolor/$resdir/apps/fastmail.png"
done
makeWrapper "${electron}/bin/electron" "$out/bin/fastmail" \
--add-flags "$out/opt/fastmail/app.asar.unpacked" \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-wayland-ime=true --wayland-text-input-version=3}}" \
--prefix LD_LIBRARY_PATH : ${finalAttrs.libPath}:$out/opt/fastmail \
--set-default ELECTRON_IS_DEV 0 \
--inherit-argv0
runHook postInstall
'';
meta = meta // {
mainProgram = "fastmail";
};
})
+20 -21
View File
@@ -1,34 +1,33 @@
{
lib,
callPackage,
stdenvNoCC,
fetchurl,
fetchzip,
}:
stdenvNoCC.mkDerivation (finalAttrs: {
let
inherit (stdenvNoCC.hostPlatform) isDarwin system;
sources = import ./sources.nix { inherit fetchurl fetchzip; };
in
callPackage (if isDarwin then ./darwin.nix else ./linux.nix) {
pname = "fastmail-desktop";
version = "1.0.0";
inherit (sources.${system} or (throw "Unsupported system: ${system}")) version src;
src = fetchzip {
url = "https://dl.fastmailcdn.com/desktop/production/mac/arm64/Fastmail-${finalAttrs.version}-arm64-mac.zip";
hash = "sha256-wIWU0F08wEQeLjbZz2LqahfyeOfowC+dDQkeMZI6gbk=";
stripRoot = false;
};
installPhase = ''
mkdir -p $out/Applications
cp -R Fastmail.app $out/Applications/
'';
dontBuild = true;
# Fastmail is notarized
dontFixup = true;
passthru.updateScript = ./update.sh;
meta = {
description = "Dedicated desktop app for Fastmail";
homepage = "https://www.fastmail.com/blog/desktop-app/";
license = lib.licenses.unfree;
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
maintainers = [ lib.maintainers.Enzime ];
platforms = [ "aarch64-darwin" ];
sourceProvenance = [ lib.sourceTypes.binaryNativeCode ];
maintainers = [
lib.maintainers.Enzime
lib.maintainers.nekowinston
];
platforms = [
"aarch64-darwin"
"x86_64-linux"
];
};
})
}
@@ -0,0 +1,20 @@
# Generated by ./update.sh - do not update manually!
# Last updated: 2025-10-30
{ fetchurl, fetchzip }:
{
aarch64-darwin = {
version = "1.0.3";
src = fetchzip {
url = "https://dl.fastmailcdn.com/desktop/production/mac/arm64/Fastmail-1.0.3-arm64-mac.zip";
hash = "sha512-lqJj0tTwOJx1jzzXtlKOOduUEtSgVHpQCM5WkbXjmOh2OejLRcdJ1Y9CxvZJGSPBGWrErKzytMOB8QmJ1BkIdw==";
stripRoot = false;
};
};
x86_64-linux = {
version = "1.0.3";
src = fetchurl {
url = "https://dl.fastmailcdn.com/desktop/production/linux/x64/Fastmail-1.0.3.AppImage";
hash = "sha512-L+h0GHAAlZndB4Q5Z7GiHuZqv1kTF5yCAJYYb9tPXnHfdcrwHvfBRnixEnVPPia46rp2IJ56z4ZS8RSut3ATFQ==";
};
};
}
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash --pure -p cacert curl yq nix
set -euo pipefail
cd "$(readlink -e "$(dirname "${BASH_SOURCE[0]}")")"
x86_64_linux_info=$(curl -fsS "https://dl.fastmailcdn.com/desktop/production/linux/x64/latest-linux.yml")
aarch64_darwin_info=$(curl -fsS "https://dl.fastmailcdn.com/desktop/production/mac/arm64/latest-mac.yml")
x86_64_linux_version=$(yq -r '.version' <<<"$x86_64_linux_info")
aarch64_darwin_version=$(yq -r '.version' <<<"$aarch64_darwin_info")
x86_64_linux_url="https://dl.fastmailcdn.com/desktop/production/linux/x64/$(yq -r '.path' <<<"$x86_64_linux_info")"
aarch64_darwin_url="https://dl.fastmailcdn.com/desktop/production/mac/arm64/$(yq -r '.path' <<<"$aarch64_darwin_info")"
x86_64_linux_hash=$(nix-hash --type sha512 --to-sri "$(yq -r '.sha512' <<<"$x86_64_linux_info")")
aarch64_darwin_hash=$(nix-hash --type sha512 --to-sri "$(yq -r '.sha512' <<<"$aarch64_darwin_info")")
cat >sources.nix <<EOF
# Generated by ./update.sh - do not update manually!
# Last updated: $(date +%F)
{ fetchurl, fetchzip }:
{
aarch64-darwin = {
version = "$aarch64_darwin_version";
src = fetchzip {
url = "$aarch64_darwin_url";
hash = "$aarch64_darwin_hash";
stripRoot = false;
};
};
x86_64-linux = {
version = "$x86_64_linux_version";
src = fetchurl {
url = "$x86_64_linux_url";
hash = "$x86_64_linux_hash";
};
};
}
EOF
+3 -3
View File
@@ -13,16 +13,16 @@
rustPlatform.buildRustPackage (finalAttrs: {
pname = "foundry";
version = "1.4.3";
version = "1.4.4";
src = fetchFromGitHub {
owner = "foundry-rs";
repo = "foundry";
tag = "v${finalAttrs.version}";
hash = "sha256-SrkFfc9+cb3nDqEOj3gRkQq9aKOSfk3s7a3EGka5ACw=";
hash = "sha256-u+JCurH1gx4onC5Poxxd9+gVrUyyebcd6xnXY4Le6Rs=";
};
cargoHash = "sha256-PoPfuMNeK6ArZddBd0lsR2r8UrvRieqkxYZ8jCCxw5o=";
cargoHash = "sha256-JLuCZckiNv0t+kPuDk6TWmPIXKOvqf3HR/oFrQ5fKKQ=";
nativeBuildInputs = [
pkg-config
+3 -3
View File
@@ -13,16 +13,16 @@
buildNpmPackage (finalAttrs: {
pname = "gemini-cli";
version = "0.10.0";
version = "0.11.3";
src = fetchFromGitHub {
owner = "google-gemini";
repo = "gemini-cli";
tag = "v${finalAttrs.version}";
hash = "sha256-h6JyiIh0+PI/5JHlztMKlXlK5XQC8x6V7Yq1VyboaXs=";
hash = "sha256-43ohCUqdM0quxwoN3s/3vOq4IRc+sck+BkAfqMEDq8g=";
};
npmDepsHash = "sha256-4RsZAs9+Q7vnRiyA1OMXC185d9Y9k6mwG+QkOE+5Pas=";
npmDepsHash = "sha256-wqzsHBFXo5NhsFHOErxVVG9Y08daEQs6YdRZHFeOq98=";
nativeBuildInputs = [
jq
+3 -3
View File
@@ -11,13 +11,13 @@
buildNpmPackage rec {
pname = "ghostfolio";
version = "2.211.0";
version = "2.214.0";
src = fetchFromGitHub {
owner = "ghostfolio";
repo = "ghostfolio";
tag = version;
hash = "sha256-RoIOk0MIf1IAQLPO4MwemkXqQfJuDZtYYqn+OS6IUb0=";
hash = "sha256-x8GUlC1/TxA40rDQu3Ae2P5v5LFtberOQWtx5GJ7rMw=";
# populate values that require us to use git. By doing this in postFetch we
# can delete .git afterwards and maintain better reproducibility of the src.
leaveDotGit = true;
@@ -27,7 +27,7 @@ buildNpmPackage rec {
'';
};
npmDepsHash = "sha256-Isy32xdxWlsGflqtcDJ6/lNaCA+IRbEOP8Z/BI0uV0s=";
npmDepsHash = "sha256-hHfT4gsf0D5XPY4RuQCKWNWp+iav9B75YMs70xayqtc=";
nativeBuildInputs = [
prisma
+2 -2
View File
@@ -8,13 +8,13 @@
buildGoModule (finalAttrs: {
pname = "go-httpbin";
version = "2.18.3";
version = "2.19.0";
src = fetchFromGitHub {
owner = "mccutchen";
repo = "go-httpbin";
tag = "v${finalAttrs.version}";
hash = "sha256-ixEbmppQ+4Udc5ytV4YPOpOT/iEbhjQIYGoOGL0dIw8=";
hash = "sha256-agElHziDwv2MGwTUKPsyDMVlTNNkuSZp4OAR2/zbW1U=";
};
vendorHash = null;
+2 -2
View File
@@ -17,13 +17,13 @@
buildGoModule rec {
pname = "grafana-alloy";
version = "1.11.2";
version = "1.11.3";
src = fetchFromGitHub {
owner = "grafana";
repo = "alloy";
tag = "v${version}";
hash = "sha256-HWnldpmt5M2+2zuEcA4doySgRyCBl4OnCCuXqtcYGkA=";
hash = "sha256-yO1r7GLXlD7f5Fpooit7SwkB7EB1hDO42o3BLvWY8Qo=";
};
proxyVendor = true;
@@ -20,14 +20,14 @@ let
in
stdenv.mkDerivation rec {
pname = "incus-ui-canonical";
version = "0.18.2";
version = "0.18.3";
src = fetchFromGitHub {
owner = "zabbly";
repo = "incus-ui-canonical";
# only use tags prefixed by incus- they are the tested fork versions
tag = "incus-${version}";
hash = "sha256-MVhyKV3NGeChsLnoKw7mC9bAQRQ9Rpg8cIWkelNFXeg=";
hash = "sha256-0wKGPH+ffJ/S8FA46ve5SzyNZJ9C2fv8Psiqu8p6D0s=";
};
offlineCache = fetchYarnDeps {
@@ -7,15 +7,15 @@
}:
let
timestamp = "202510022025";
timestamp = "202510301627";
in
stdenv.mkDerivation (finalAttrs: {
pname = "jdt-language-server";
version = "1.51.0";
version = "1.52.0";
src = fetchurl {
url = "https://download.eclipse.org/jdtls/milestones/${finalAttrs.version}/jdt-language-server-${finalAttrs.version}-${timestamp}.tar.gz";
hash = "sha256-ilk3IReIG/W9wCIPIlRHKEa4gTfAWPNEsAp9QUJ3RaE=";
hash = "sha256-V+a0U2ZTVLQqiYgn0quTij7GtBwScsEJmDw7emDsR4U=";
};
sourceRoot = ".";
+11 -2
View File
@@ -7,6 +7,7 @@
lib,
stdenv,
makeSetupHook,
runCommand,
makeBinaryWrapper,
pkg-config,
targetPackages,
@@ -44,8 +45,16 @@ makeSetupHook {
];
substitutions = {
fallbackXdgDirs = "${lib.optionalString includeSettings "${targetPackages.cosmic-settings}/share:"}${targetPackages.cosmic-icons}/share";
fallbackXdgDirs =
let
fallbackThemes = runCommand "cosmic-fallback-themes" { } ''
mkdir -p $out/share
ln -s ${targetPackages.cosmic-settings}/share/cosmic $out/share/cosmic
'';
in
lib.makeSearchPath "share" (
lib.optionals includeSettings [ fallbackThemes ] ++ [ targetPackages.cosmic-icons ]
);
cargoLinkerVar = targetPackages.stdenv.hostPlatform.rust.cargoEnvVarTarget;
# force linking for all libraries that may be dlopen'd by libcosmic/iced apps
cargoLinkLibs = lib.escapeShellArgs (
+7 -1
View File
@@ -234,7 +234,13 @@ stdenv.mkDerivation (finalAttrs: {
substituteInPlace src/output/plugins/OSXOutputPlugin.cxx \
--replace kAudioObjectPropertyElement{Main,Master} \
--replace kAudioHardwareServiceDeviceProperty_Virtual{Main,Master}Volume
'';
''
+
lib.optionalString
(stdenv.hostPlatform.isDarwin && lib.versionOlder stdenv.hostPlatform.darwinSdkVersion "13.3")
''
sed -i "/subdir('time')/d" test/meson.build
'';
# Otherwise, the meson log says:
#
+2 -2
View File
@@ -6,13 +6,13 @@
buildGoModule rec {
pname = "nakama";
version = "3.32.1";
version = "3.33.0";
src = fetchFromGitHub {
owner = "heroiclabs";
repo = "nakama";
tag = "v${version}";
hash = "sha256-guoKppChjT4f1IOM4Cxg6XZkJrYNVv9gwOTy57t7wDs=";
hash = "sha256-GiUufoWLwWBuZxId+vMkJPaJIb/FWLJAJLb7WKoyn5M=";
};
vendorHash = null;
@@ -8,15 +8,15 @@
stdenvNoCC.mkDerivation {
pname = "pop-hp-wallpapers";
version = "0-unstable-2022-04-01";
version = "0-unstable-2025-10-28";
src = fetchFromGitHub {
owner = "pop-os";
repo = "hp-wallpapers";
rev = "df86078846b0a2a4e3e64f584aaf2a21be47a7eb";
rev = "94f7df30f6bf1c3d71522018852d77c10b920ea3";
forceFetchGit = true;
fetchLFS = true;
hash = "sha256-NGSvPC9GadqqqgGH9uDNAYuSwfagosmCAE6QmDtmdMw=";
hash = "sha256-AthVQ9kQO+CvSH1xxz/U6WzAtpcXK1gvRwKyeo0vMSs=";
};
nativeBuildInputs = [ imagemagick ];
@@ -8,22 +8,22 @@
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "postgres-language-server";
version = "0.16.1";
version = "0.17.2";
src = fetchgit {
url = "https://github.com/supabase-community/postgres-language-server";
tag = finalAttrs.version;
hash = "sha256-zdFgfZ9GtZObn839kkAIT71bBt7YHs28qkAWlp3k7kw=";
hash = "sha256-gUE6OlDFlqS+Y+gX1qYs2E8sJfNUSmS/ypMsh/q7VtE=";
fetchSubmodules = true;
};
cargoHash = "sha256-psgo5/tDHaQd0dkiD/3uhrKuxlOBLi/xG4x3gVPLZbw=";
cargoHash = "sha256-QP63SmAxjMdoz3yHLkvgM8xRleHXQmSRwTkyghbvJ+c=";
nativeBuildInputs = [
rustPlatform.bindgenHook
# Required to build the custom tree-sitter grammar
# https://github.com/supabase-community/postgres-language-server/blob/main/crates/pgt_treesitter_grammar/grammar.js
# https://github.com/supabase-community/postgres-language-server/blob/main/crates/pgls_treesitter_grammar/grammar.js
tree-sitter
nodejs
];
@@ -37,10 +37,10 @@ rustPlatform.buildRustPackage (finalAttrs: {
# As specified in the upstream: https://github.com/supabase-community/postgres-language-server/blob/main/.github/workflows/release.yml
RUSTFLAGS = "-C strip=symbols -C codegen-units=1";
PGT_VERSION = finalAttrs.version;
PGLS_VERSION = finalAttrs.version;
};
cargoBuildFlags = [ "-p=pgt_cli" ];
cargoBuildFlags = [ "-p=pgls_cli" ];
cargoTestFlags = finalAttrs.cargoBuildFlags;
checkFlags = [
# Tries to write to the file system relatively to the current path
+2 -2
View File
@@ -11,13 +11,13 @@ let
in
stdenv.mkDerivation (finalAttrs: {
pname = "protoc-gen-swift";
version = "1.32.0";
version = "1.33.3";
src = fetchFromGitHub {
owner = "apple";
repo = "swift-protobuf";
rev = "${finalAttrs.version}";
hash = "sha256-YirKJjEA5zFVVs8U1/D3TYCgv+3FMO7dusCZ7ZuIeZs=";
hash = "sha256-FFFHnxuynKfcmWCgJ38rKk3FS/o5buLYS7VcEivF0v0=";
};
nativeBuildInputs = [
+2 -2
View File
@@ -9,13 +9,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "quickjs-ng";
version = "0.10.1";
version = "0.11.0";
src = fetchFromGitHub {
owner = "quickjs-ng";
repo = "quickjs";
tag = "v${finalAttrs.version}";
hash = "sha256-WtjHyqxibP6bAO9HsXuqAW/Y1qgt/Tpj401CIk4bY7o=";
hash = "sha256-Mb0YyxTWU6a8HFTVBmlJ5yGEDmjKXHqTSszAvb8Y01U=";
};
outputs = [
+3 -3
View File
@@ -16,18 +16,18 @@
rustPlatform.buildRustPackage (finalAttrs: {
pname = "ruff";
version = "0.14.2";
version = "0.14.3";
src = fetchFromGitHub {
owner = "astral-sh";
repo = "ruff";
tag = finalAttrs.version;
hash = "sha256-bHcmnfbdPzCX/Eqy5o+hVqhggfsPwZeUVjXV9wF6fNE=";
hash = "sha256-iYXZyB0s3rlGV3HQLN1fuAohFUm/53VLAwA3Ahj6HzM=";
};
cargoBuildFlags = [ "--package=ruff" ];
cargoHash = "sha256-lAluzoRONfkyspcMCp7wNei0R3dgpAwwwpRAmbTNl1k=";
cargoHash = "sha256-dYXFNe+nglKelgzi2Afo0AJyt53qfCAJ7reTMMfjWOI=";
nativeBuildInputs = [ installShellFiles ];
+3
View File
@@ -7,6 +7,7 @@
yaml-cpp,
pkg-config,
procps,
coreutils,
smartSupport ? false,
libatasmart,
}:
@@ -31,6 +32,8 @@ stdenv.mkDerivation (finalAttrs: {
+ ''
substituteInPlace rcscripts/systemd/thinkfan-sleep.service \
--replace-fail "/usr/bin/pkill" "${lib.getExe' procps "pkill"}"
substituteInPlace rcscripts/systemd/thinkfan-sleep.service \
--replace-fail "ExecStart=sleep " "ExecStart=${lib.getExe' coreutils "sleep"} "
substituteInPlace rcscripts/systemd/thinkfan-wakeup.service \
--replace-fail "/usr/bin/pkill" "${lib.getExe' procps "pkill"}"
substituteInPlace rcscripts/systemd/thinkfan.service.cmake \
+3 -3
View File
@@ -8,8 +8,8 @@
ncurses,
pkg-config,
runCommand,
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
systemd,
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemdLibs,
systemdLibs,
# broken on i686-linux https://github.com/tmux/tmux/issues/4597
withUtf8proc ? !(stdenv.hostPlatform.is32bit),
utf8proc, # gets Unicode updates faster than glibc
@@ -55,7 +55,7 @@ stdenv.mkDerivation (finalAttrs: {
ncurses
libevent
]
++ lib.optionals withSystemd [ systemd ]
++ lib.optionals withSystemd [ systemdLibs ]
++ lib.optionals withUtf8proc [ utf8proc ]
++ lib.optionals withUtempter [ libutempter ];
+2 -2
View File
@@ -13,13 +13,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "vivify";
version = "0.10.0";
version = "0.11.0";
src = fetchFromGitHub {
owner = "jannis-baum";
repo = "Vivify";
tag = "v${finalAttrs.version}";
hash = "sha256-n2l0+CFQ7EXnTZXr+JO7NE1OVSzpphs6lUgHfjebX4M=";
hash = "sha256-LQX7HBTWDR43aMqJrogL9rDFL5qRF0Xzw/O35Uq7R3g=";
};
yarnOfflineCache = fetchYarnDeps {
+9 -9
View File
@@ -1,20 +1,20 @@
{
"aarch64-darwin": {
"version": "1.12.25",
"version": "1.12.27",
"vscodeVersion": "1.105.0",
"url": "https://windsurf-stable.codeiumdata.com/darwin-arm64/stable/3dde4f1e45c3c089540abe588074eb5a4fe122c3/Windsurf-darwin-arm64-1.12.25.zip",
"sha256": "9fba99838189f4ad12ec35c0f0ee97e99652b43492fb19fe17908848a5f2b13c"
"url": "https://windsurf-stable.codeiumdata.com/darwin-arm64/stable/94ec85969ebc38d14c35c87a0284fafd84bff116/Windsurf-darwin-arm64-1.12.27.zip",
"sha256": "294f3a3aab7665caf936ef43b384540695849928c956c28b4b783bb3b34913a2"
},
"x86_64-darwin": {
"version": "1.12.25",
"version": "1.12.27",
"vscodeVersion": "1.105.0",
"url": "https://windsurf-stable.codeiumdata.com/darwin-x64/stable/3dde4f1e45c3c089540abe588074eb5a4fe122c3/Windsurf-darwin-x64-1.12.25.zip",
"sha256": "893b0cf579b4fa4354f5f014b9caf8f0e7ae9f98b9bb0d4b597e2322863eb278"
"url": "https://windsurf-stable.codeiumdata.com/darwin-x64/stable/94ec85969ebc38d14c35c87a0284fafd84bff116/Windsurf-darwin-x64-1.12.27.zip",
"sha256": "61e0dac30fa014f42f99138434f289504d4d2a79aaa9f4cc61c30c663c6ab979"
},
"x86_64-linux": {
"version": "1.12.25",
"version": "1.12.27",
"vscodeVersion": "1.105.0",
"url": "https://windsurf-stable.codeiumdata.com/linux-x64/stable/3dde4f1e45c3c089540abe588074eb5a4fe122c3/Windsurf-linux-x64-1.12.25.tar.gz",
"sha256": "c170f3249c95220b8e1b26feb4f2452d4a8be5dcbcfb2a1f1768fb0c0137101e"
"url": "https://windsurf-stable.codeiumdata.com/linux-x64/stable/94ec85969ebc38d14c35c87a0284fafd84bff116/Windsurf-linux-x64-1.12.27.tar.gz",
"sha256": "8f380755df34a1b466c28448f22fc92d3cfb13da55e9d8f2c9db5a4db83f6cac"
}
}
@@ -57,11 +57,12 @@ stdenv.mkDerivation (finalAttrs: {
passthru.updateScript = gitUpdater { rev-prefix = "xfce4-panel-profiles-"; };
meta = with lib; {
meta = {
homepage = "https://docs.xfce.org/apps/xfce4-panel-profiles/start";
description = "Simple application to manage Xfce panel layouts";
license = lib.licenses.gpl3Plus;
mainProgram = "xfce4-panel-profiles";
teams = [ teams.xfce ];
platforms = platforms.linux;
teams = [ lib.teams.xfce ];
platforms = lib.platforms.linux;
};
})
@@ -14,12 +14,12 @@
let
pname = "ex_doc";
version = "0.39.0";
version = "0.39.1";
src = fetchFromGitHub {
owner = "elixir-lang";
repo = "${pname}";
rev = "v${version}";
hash = "sha256-7f4TQgQIeWb+SRMYLsqnOWnPHY7Pqi8qtruVe8OaZRY=";
hash = "sha256-edK484d5Fn5Kb/UEV1g3XinFF1rQJ1DypLEueET//Bg=";
};
in
mixRelease {
@@ -1,6 +1,6 @@
import ./generic-builder.nix {
version = "1.19.1";
hash = "sha256-0rJx1BoJGDS0FsXyngBfQL3LhhNZvwh+TLQZjqOPFQw=";
version = "1.19.2";
hash = "sha256-sJNwWl6iCWzf8iDVG90DUxU8H3piKyGoU0mIAqfsphQ=";
# https://hexdocs.pm/elixir/1.19.0-rc.1/compatibility-and-deprecations.html#between-elixir-and-erlang-otp
minimumOTPVersion = "26";
maximumOTPVersion = "28";
@@ -12,14 +12,14 @@
buildPythonPackage rec {
pname = "cysignals";
version = "1.12.5";
version = "1.12.6";
pyproject = true;
src = fetchFromGitHub {
owner = "sagemath";
repo = "cysignals";
tag = version;
hash = "sha256-y7CA0aih2vATLz0Fhwf19/wRw6GnQvNhGo9lS4+VrgI=";
hash = "sha256-uZNKmnn1Jf1pERdG4bywpAUClKMw3og+7Q5B0yPlqEY=";
};
build-system = [
@@ -9,14 +9,14 @@
buildPythonPackage rec {
pname = "onedrive-personal-sdk";
version = "0.0.14";
version = "0.0.15";
pyproject = true;
src = fetchFromGitHub {
owner = "zweckj";
repo = "onedrive-personal-sdk";
tag = "v${version}";
hash = "sha256-WdnkIMmTzvid2bl7n9NHMtF153O91hutMib8bs5BgIs=";
hash = "sha256-XKFTwaerAtN0GEZGpJ4Uq81cIrENEkNFhqqqM+eNVII=";
};
build-system = [ setuptools ];
+8 -8
View File
@@ -5,21 +5,21 @@
lib,
stdenv,
}:
buildGoModule rec {
buildGoModule (finalAttrs: {
pname = "devbox";
version = "0.16.0";
src = fetchFromGitHub {
owner = "jetify-com";
repo = pname;
rev = version;
repo = "devbox";
tag = finalAttrs.version;
hash = "sha256-+OsFKBtc4UkkI37YJM9uKIJZC1+KkuDJJKjipRzyF7k=";
};
ldflags = [
"-s"
"-w"
"-X go.jetify.com/devbox/internal/build.Version=${version}"
"-X go.jetify.com/devbox/internal/build.Version=${finalAttrs.version}"
];
subPackages = [ "cmd/devbox" ];
@@ -38,14 +38,14 @@ buildGoModule rec {
--zsh <($out/bin/devbox completion zsh)
'';
meta = with lib; {
meta = {
description = "Instant, easy, predictable shells and containers";
homepage = "https://www.jetify.com/devbox";
license = licenses.asl20;
maintainers = with maintainers; [
license = lib.licenses.asl20;
maintainers = with lib.maintainers; [
urandom
lagoja
madeddie
];
};
}
})
+86 -105
View File
@@ -77,7 +77,7 @@ let
# FIXME: figure out how to actually make BTFs reproducible instead
# See https://github.com/NixOS/nixpkgs/pull/181456 for details.
MODULE_ALLOW_BTF_MISMATCH = whenAtLeast "5.18" (option yes);
BPF_LSM = whenAtLeast "5.7" (option yes);
BPF_LSM = option yes;
DEBUG_KERNEL = yes;
DEBUG_DEVRES = no;
DYNAMIC_DEBUG = yes;
@@ -154,10 +154,10 @@ let
CPU_FREQ_STAT = yes;
# Enable CPU energy model for scheduling
ENERGY_MODEL = whenAtLeast "5.0" yes;
ENERGY_MODEL = yes;
# Enable thermal interface netlink API
THERMAL_NETLINK = whenAtLeast "5.9" yes;
THERMAL_NETLINK = yes;
# Prefer power-efficient workqueue implementation to per-CPU workqueues,
# which is slightly slower, but improves battery life.
@@ -182,24 +182,24 @@ let
X86_INTEL_PSTATE = yes;
X86_AMD_PSTATE = whenAtLeast "5.17" yes;
# Intel DPTF (Dynamic Platform and Thermal Framework) Support
ACPI_DPTF = whenAtLeast "5.10" yes;
ACPI_DPTF = yes;
# Required to bring up some Bay Trail devices properly
I2C = yes;
I2C_DESIGNWARE_CORE = yes;
I2C_DESIGNWARE_PLATFORM = yes;
PMIC_OPREGION = whenAtLeast "5.10" yes;
INTEL_SOC_PMIC = whenAtLeast "5.10" yes;
BYTCRC_PMIC_OPREGION = whenAtLeast "5.10" yes;
CHTCRC_PMIC_OPREGION = whenAtLeast "5.10" yes;
XPOWER_PMIC_OPREGION = whenAtLeast "5.10" yes;
BXT_WC_PMIC_OPREGION = whenAtLeast "5.10" yes;
INTEL_SOC_PMIC_CHTWC = whenAtLeast "5.10" yes;
CHT_WC_PMIC_OPREGION = whenAtLeast "5.10" yes;
INTEL_SOC_PMIC_CHTDC_TI = whenAtLeast "5.10" yes;
CHT_DC_TI_PMIC_OPREGION = whenAtLeast "5.10" yes;
MFD_TPS68470 = whenBetween "5.10" "5.13" yes;
TPS68470_PMIC_OPREGION = whenAtLeast "5.10" yes;
PMIC_OPREGION = yes;
INTEL_SOC_PMIC = yes;
BYTCRC_PMIC_OPREGION = yes;
CHTCRC_PMIC_OPREGION = yes;
XPOWER_PMIC_OPREGION = yes;
BXT_WC_PMIC_OPREGION = yes;
INTEL_SOC_PMIC_CHTWC = yes;
CHT_WC_PMIC_OPREGION = yes;
INTEL_SOC_PMIC_CHTDC_TI = yes;
CHT_DC_TI_PMIC_OPREGION = yes;
MFD_TPS68470 = whenOlder "5.13" yes;
TPS68470_PMIC_OPREGION = yes;
# Enable Intel thermal hardware feedback
INTEL_HFI_THERMAL = whenAtLeast "5.18" yes;
@@ -251,11 +251,9 @@ let
# Include the CFQ I/O scheduler in the kernel, rather than as a
# module, so that the initrd gets a good I/O scheduler.
scheduler = {
IOSCHED_CFQ = whenOlder "5.0" yes; # Removed in 5.0-RC1
BLK_CGROUP = yes; # required by CFQ"
BLK_CGROUP_IOLATENCY = yes;
BLK_CGROUP_IOCOST = yes;
IOSCHED_DEADLINE = whenOlder "5.0" yes; # Removed in 5.0-RC1
MQ_IOSCHED_DEADLINE = yes;
BFQ_GROUP_IOSCHED = yes;
MQ_IOSCHED_KYBER = yes;
@@ -379,13 +377,13 @@ let
INET_DIAG_DESTROY = lib.mkDefault yes;
# IPsec over TCP
INET_ESPINTCP = whenAtLeast "5.8" yes;
INET6_ESPINTCP = whenAtLeast "5.8" yes;
INET_ESPINTCP = yes;
INET6_ESPINTCP = yes;
# enable multipath-tcp
MPTCP = whenAtLeast "5.6" yes;
MPTCP_IPV6 = whenAtLeast "5.6" yes;
INET_MPTCP_DIAG = whenAtLeast "5.9" (lib.mkDefault module);
MPTCP = yes;
MPTCP_IPV6 = yes;
INET_MPTCP_DIAG = lib.mkDefault module;
# Kernel TLS
TLS = module;
@@ -444,14 +442,8 @@ let
RTL8XXXU_UNTESTED = option yes;
RTW88 = module;
RTW88_8822BE = lib.mkMerge [
(whenOlder "5.8" yes)
(whenAtLeast "5.8" module)
];
RTW88_8822CE = lib.mkMerge [
(whenOlder "5.8" yes)
(whenAtLeast "5.8" module)
];
RTW88_8822BE = module;
RTW88_8822CE = module;
};
fb = {
@@ -483,7 +475,7 @@ let
FONT_8x8 = yes;
FONT_8x16 = yes;
# High DPI font
FONT_TER16x32 = whenAtLeast "5.0" yes;
FONT_TER16x32 = yes;
};
video =
@@ -494,7 +486,7 @@ let
|| isPower64
|| isS390x
|| isx86_64
|| (lib.versionAtLeast version "5.7" && isAarch64)
|| isAarch64
|| (lib.versionAtLeast version "6.11" && isRiscV64)
);
in
@@ -530,18 +522,15 @@ let
DRM_DP_AUX_CHARDEV = whenOlder "6.10" yes;
DRM_DISPLAY_DP_AUX_CHARDEV = whenAtLeast "6.10" yes;
# amdgpu display core (DC) support
DRM_AMD_DC_DCN1_0 = lib.mkIf stdenv.hostPlatform.isx86 (whenOlder "5.6" yes);
DRM_AMD_DC_DCN2_0 = lib.mkIf stdenv.hostPlatform.isx86 (whenOlder "5.6" yes);
DRM_AMD_DC_DCN2_1 = lib.mkIf stdenv.hostPlatform.isx86 (whenOlder "5.6" yes);
DRM_AMD_DC_DCN3_0 = lib.mkIf (with stdenv.hostPlatform; isx86) (whenBetween "5.9" "5.11" yes);
DRM_AMD_DC_DCN3_0 = lib.mkIf (with stdenv.hostPlatform; isx86) (whenOlder "5.11" yes);
DRM_AMD_DC_DCN = lib.mkIf (with stdenv.hostPlatform; isx86 || isPower64) (
whenBetween "5.11" "6.4" yes
);
# Not available when using clang
# See: https://github.com/torvalds/linux/blob/172a9d94339cea832d89630b89d314e41d622bd8/drivers/gpu/drm/amd/display/Kconfig#L14
DRM_AMD_DC_FP = lib.mkIf (!stdenv.cc.isClang) (whenAtLeast "6.4" yes);
DRM_AMD_DC_HDCP = whenBetween "5.5" "6.4" yes;
DRM_AMD_DC_SI = whenAtLeast "5.10" yes;
DRM_AMD_DC_HDCP = whenOlder "6.4" yes;
DRM_AMD_DC_SI = yes;
# Enable AMD Audio Coprocessor support for HDMI outputs
DRM_AMD_ACP = yes;
@@ -567,7 +556,7 @@ let
# Enable HDMI-CEC receiver support
RC_CORE = yes;
MEDIA_CEC_RC = whenAtLeast "5.10" yes;
MEDIA_CEC_RC = yes;
# Enable CEC over DisplayPort
DRM_DP_CEC = whenOlder "6.10" yes;
@@ -619,48 +608,43 @@ let
SND_HDA_RECONFIG = yes; # Support reconfiguration of jack functions
# Support configuring jack functions via fw mechanism at boot
SND_HDA_PATCH_LOADER = yes;
SND_HDA_CODEC_CA0132_DSP = whenOlder "5.7" yes; # Enable DSP firmware loading on Creative Soundblaster Z/Zx/ZxR/Recon
SND_HDA_CODEC_CS8409 = whenAtLeast "6.6" module; # Cirrus Logic HDA Bridge CS8409
SND_OSSEMUL = yes;
SND_USB_CAIAQ_INPUT = yes;
SND_USB_AUDIO_MIDI_V2 = whenAtLeast "6.5" yes;
# Enable Sound Open Firmware support
}
//
lib.optionalAttrs (stdenv.hostPlatform.system == "x86_64-linux" && lib.versionAtLeast version "5.5")
{
SND_SOC_INTEL_SOUNDWIRE_SOF_MACH = whenAtLeast "5.10" module;
SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES = whenAtLeast "5.10" yes; # dep of SOF_MACH
SND_SOC_SOF_INTEL_SOUNDWIRE_LINK = whenBetween "5.10" "5.11" yes; # dep of SOF_MACH
SND_SOC_SOF_TOPLEVEL = yes;
SND_SOC_SOF_ACPI = module;
SND_SOC_SOF_PCI = module;
SND_SOC_SOF_APOLLOLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_APOLLOLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_CANNONLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_CANNONLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_COFFEELAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_COFFEELAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_COMETLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_COMETLAKE_H_SUPPORT = whenOlder "5.8" yes;
SND_SOC_SOF_COMETLAKE_LP_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_ELKHARTLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_ELKHARTLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_GEMINILAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_GEMINILAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_HDA_AUDIO_CODEC = yes;
SND_SOC_SOF_HDA_COMMON_HDMI_CODEC = whenOlder "5.7" yes;
SND_SOC_SOF_HDA_LINK = yes;
SND_SOC_SOF_ICELAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_ICELAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_INTEL_TOPLEVEL = yes;
SND_SOC_SOF_JASPERLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_JASPERLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_MERRIFIELD = whenAtLeast "5.12" module;
SND_SOC_SOF_MERRIFIELD_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_TIGERLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_TIGERLAKE_SUPPORT = whenOlder "5.12" yes;
};
// lib.optionalAttrs (stdenv.hostPlatform.system == "x86_64-linux") {
SND_SOC_INTEL_SOUNDWIRE_SOF_MACH = module;
SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES = yes; # dep of SOF_MACH
SND_SOC_SOF_INTEL_SOUNDWIRE_LINK = whenOlder "5.11" yes; # dep of SOF_MACH
SND_SOC_SOF_TOPLEVEL = yes;
SND_SOC_SOF_ACPI = module;
SND_SOC_SOF_PCI = module;
SND_SOC_SOF_APOLLOLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_APOLLOLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_CANNONLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_CANNONLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_COFFEELAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_COFFEELAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_COMETLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_COMETLAKE_LP_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_ELKHARTLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_ELKHARTLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_GEMINILAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_GEMINILAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_HDA_AUDIO_CODEC = yes;
SND_SOC_SOF_HDA_LINK = yes;
SND_SOC_SOF_ICELAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_ICELAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_INTEL_TOPLEVEL = yes;
SND_SOC_SOF_JASPERLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_JASPERLAKE_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_MERRIFIELD = whenAtLeast "5.12" module;
SND_SOC_SOF_MERRIFIELD_SUPPORT = whenOlder "5.12" yes;
SND_SOC_SOF_TIGERLAKE = whenAtLeast "5.12" module;
SND_SOC_SOF_TIGERLAKE_SUPPORT = whenOlder "5.12" yes;
};
usb = {
USB = yes; # compile USB core into kernel, so we can use USB_SERIAL_CONSOLE before modules
@@ -680,7 +664,7 @@ let
USB_SERIAL = yes;
USB_SERIAL_GENERIC = yes; # USB Generic Serial Driver
USB_SERIAL_CONSOLE = yes; # Allow using USB serial adapter as console
U_SERIAL_CONSOLE = whenAtLeast "5.10" yes; # Allow using USB gadget as console
U_SERIAL_CONSOLE = yes; # Allow using USB gadget as console
};
# Filesystem options - in particular, enable extended attributes and
@@ -730,11 +714,9 @@ let
F2FS_FS = module;
F2FS_FS_SECURITY = option yes;
F2FS_FS_COMPRESSION = whenAtLeast "5.6" yes;
F2FS_FS_COMPRESSION = yes;
UDF_FS = module;
NFSD_V2_ACL = whenOlder "5.10" yes;
NFSD_V3 = whenOlder "5.10" yes;
NFSD_V3_ACL = yes;
NFSD_V4 = yes;
NFSD_V4_SECURITY_LABEL = yes;
@@ -815,10 +797,9 @@ let
SECURITY_DMESG_RESTRICT = yes;
RANDOM_TRUST_CPU = lib.mkIf (
with stdenv.hostPlatform;
isPower64 || isS390 || isx86 || (lib.versionAtLeast version "5.6" && isAarch64)
) (whenOlder "6.2" yes); # allow RDRAND to seed the RNG
RANDOM_TRUST_CPU = lib.mkIf (with stdenv.hostPlatform; isPower64 || isS390 || isx86 || isAarch64) (
whenOlder "6.2" yes
); # allow RDRAND to seed the RNG
RANDOM_TRUST_BOOTLOADER = whenOlder "6.2" yes; # allow the bootloader to seed the RNG
MODULE_SIG = no; # r13y, generates a random key during build and bakes it in
@@ -941,7 +922,7 @@ let
STACK_TRACER = yes;
UPROBE_EVENTS = option yes;
BPF_SYSCALL = yes;
BPF_UNPRIV_DEFAULT_OFF = whenBetween "5.10" "5.16" yes;
BPF_UNPRIV_DEFAULT_OFF = whenOlder "5.16" yes;
BPF_EVENTS = yes;
FUNCTION_PROFILER = yes;
RING_BUFFER_BENCHMARK = no;
@@ -1035,7 +1016,7 @@ let
ZRAM_BACKEND_ZSTD = whenAtLeast "6.12" yes;
ZRAM_DEF_COMP_ZSTD = whenAtLeast "5.11" yes;
ZSWAP = option yes;
ZSWAP_COMPRESSOR_DEFAULT_ZSTD = whenAtLeast "5.7" (lib.mkOptionDefault yes);
ZSWAP_COMPRESSOR_DEFAULT_ZSTD = lib.mkOptionDefault yes;
ZPOOL = whenOlder "6.18" yes;
ZSMALLOC = option yes;
};
@@ -1065,8 +1046,7 @@ let
LOCK_TORTURE_TEST = option no;
MTD_TESTS = option no;
NOTIFIER_ERROR_INJECTION = option no;
RCU_PERF_TEST = whenOlder "5.9" no;
RCU_SCALE_TEST = whenAtLeast "5.10" no;
RCU_SCALE_TEST = no;
TEST_ASYNC_DRIVER_PROBE = option no;
WW_MUTEX_SELFTEST = option no;
XZ_DEC_TEST = option no;
@@ -1086,7 +1066,7 @@ let
let
# Use zstd for kernel compression if 64-bit and newer than 5.9, otherwise xz.
# i686 issues: https://github.com/NixOS/nixpkgs/pull/117961#issuecomment-812106375
useZstd = stdenv.buildPlatform.is64bit && lib.versionAtLeast version "5.9";
useZstd = stdenv.buildPlatform.is64bit;
in
{
# stdenv.hostPlatform.linux-kernel.target assumes uncompressed on RISC-V.
@@ -1181,9 +1161,9 @@ let
BLK_SED_OPAL = yes;
# Enable support for block layer inline encryption
BLK_INLINE_ENCRYPTION = whenAtLeast "5.8" yes;
BLK_INLINE_ENCRYPTION = yes;
# ...but fall back to CPU encryption if unavailable
BLK_INLINE_ENCRYPTION_FALLBACK = whenAtLeast "5.8" yes;
BLK_INLINE_ENCRYPTION_FALLBACK = yes;
BSD_PROCESS_ACCT_V3 = yes;
@@ -1213,7 +1193,7 @@ let
EFI = lib.mkIf stdenv.hostPlatform.isEfi yes;
EFI_STUB = yes; # EFI bootloader in the bzImage itself
EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER = whenOlder "6.2" (whenAtLeast "5.8" yes); # initrd kernel parameter for EFI
EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER = whenOlder "6.2" yes; # initrd kernel parameter for EFI
# Generic compression support for EFI payloads
# Add new platforms only after they have been verified to build and boot.
@@ -1261,7 +1241,7 @@ let
NVME_TCP_TLS = whenAtLeast "6.7" yes;
NVME_TARGET = module;
NVME_TARGET_PASSTHRU = whenAtLeast "5.9" yes;
NVME_TARGET_PASSTHRU = yes;
NVME_TARGET_AUTH = whenAtLeast "6.0" yes;
NVME_TARGET_TCP_TLS = whenAtLeast "6.7" yes;
@@ -1271,7 +1251,7 @@ let
|| isPower64
|| isS390x
|| isx86_64
|| (lib.versionAtLeast version "5.7" && isAarch64)
|| isAarch64
|| (lib.versionAtLeast version "6.11" && isRiscV64)
) yes;
@@ -1313,7 +1293,7 @@ let
HWMON = yes;
THERMAL_HWMON = yes; # Hardware monitoring support
NVME_HWMON = whenAtLeast "5.5" yes; # NVMe drives temperature reporting
NVME_HWMON = yes; # NVMe drives temperature reporting
UEVENT_HELPER = no;
USERFAULTFD = yes;
@@ -1346,7 +1326,7 @@ let
|| isPower64
|| isS390x
|| isx86_64
|| (lib.versionAtLeast version "5.7" && isAarch64)
|| isAarch64
|| (lib.versionAtLeast version "6.11" && isRiscV64)
) yes;
@@ -1387,15 +1367,15 @@ let
};
ANDROID_BINDER_IPC = {
optional = true;
tristate = whenAtLeast "5.0" "y";
tristate = "y";
};
ANDROID_BINDERFS = {
optional = true;
tristate = whenAtLeast "5.0" "y";
tristate = "y";
};
ANDROID_BINDER_DEVICES = {
optional = true;
freeform = whenAtLeast "5.0" "binder,hwbinder,vndbinder";
freeform = "binder,hwbinder,vndbinder";
};
TASKSTATS = yes;
@@ -1403,12 +1383,14 @@ let
TASK_XACCT = yes;
TASK_IO_ACCOUNTING = yes;
LEGACY_TIOCSTI = whenAtLeast "6.2" no;
# Fresh toolchains frequently break -Werror build for minor issues.
WERROR = whenAtLeast "5.15" no;
# > CONFIG_KUNIT should not be enabled in a production environment. Enabling KUnit disables Kernel Address-Space Layout Randomization (KASLR), and tests may affect the state of the kernel in ways not suitable for production.
# https://www.kernel.org/doc/html/latest/dev-tools/kunit/start.html
KUNIT = whenAtLeast "5.5" no;
KUNIT = no;
# Set system time from RTC on startup and resume
RTC_HCTOSYS = option yes;
@@ -1418,7 +1400,7 @@ let
# Enable generic kernel watch queues
# See https://docs.kernel.org/core-api/watch_queue.html
WATCH_QUEUE = whenAtLeast "5.8" yes;
WATCH_QUEUE = yes;
}
//
lib.optionalAttrs
@@ -1437,7 +1419,7 @@ let
|| isPower
|| isS390
|| isx86
|| (lib.versionAtLeast version "5.7" && isAarch64)
|| isAarch64
|| (lib.versionAtLeast version "6.11" && isRiscV)
) yes;
HOTPLUG_CPU = yes;
@@ -1458,8 +1440,7 @@ let
CROS_EC_I2C = module;
CROS_EC_SPI = module;
CROS_KBD_LED_BACKLIGHT = module;
MFD_CROS_EC = whenOlder "5.10" module;
TCG_TIS_SPI_CR50 = whenAtLeast "5.5" yes;
TCG_TIS_SPI_CR50 = yes;
}
//
lib.optionalAttrs
@@ -1521,7 +1502,7 @@ let
CHROMEOS_PSTORE = module;
# Enable x86 resource control
X86_CPU_RESCTRL = whenAtLeast "5.0" yes;
X86_CPU_RESCTRL = yes;
# Enable TSX on CPUs where it's not vulnerable
X86_INTEL_TSX_MODE_AUTO = yes;
@@ -20,18 +20,18 @@
"lts": true
},
"6.6": {
"version": "6.6.115",
"hash": "sha256:0iwhzlrqcw9hzr21gn0pmsjix0d022a7g38vszx4jsqgimgc160a",
"version": "6.6.116",
"hash": "sha256:07d5629579apc1d8yb0ki226iyb5n3lwp1yw0p189qlvq919g9d9",
"lts": true
},
"6.12": {
"version": "6.12.56",
"hash": "sha256:15pclwn3nbwccdfwcqd3lkmdxwpjkmadhj63acqbzxsjycm2nhsm",
"version": "6.12.57",
"hash": "sha256:06jlsawz1wgk13gyxphkglb8a4iiwg0vg5hrfc7bj1s6gk1s2p0n",
"lts": true
},
"6.17": {
"version": "6.17.6",
"hash": "sha256:17662dpl1rd24n20ihb1fsf66c8n3r6x1a24c6sanj1ld5mvrkwf",
"version": "6.17.7",
"hash": "sha256:03lxl2p8hvi4hdzbf72v3xh8yigr58826dmy6rqxbq9r8h6ymwnx",
"lts": false
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@
postgresqlBuildExtension (finalAttrs: {
pname = "pg_repack";
version = "1.5.2";
version = "1.5.3";
buildInputs = postgresql.buildInputs;
@@ -18,7 +18,7 @@ postgresqlBuildExtension (finalAttrs: {
owner = "reorg";
repo = "pg_repack";
tag = "ver_${finalAttrs.version}";
hash = "sha256-wfjiLkx+S3zVrAynisX1GdazueVJ3EOwQEPcgUQt7eA=";
hash = "sha256-Ufh/dKrKumRKeQ/CpwvxbjAmgILAn04BduPZMRvS+nU=";
};
passthru.updateScript = gitUpdater {