mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-21 08:01:31 +00:00
Merge master into staging-next
This commit is contained in:
11
ci/README.md
11
ci/README.md
@@ -51,6 +51,16 @@ To ensure security and a focused utility, the bot adheres to specific limitation
|
||||
- opened 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.
|
||||
- No [committer][@NixOS/nixpkgs-committers] has an outstanding "changes requested" review.
|
||||
These block both the merge queue and auto-merge, so the bot refuses to merge until the review is addressed or dismissed.
|
||||
|
||||
Once these constraints are met, the bot picks a merge strategy based on the `no PR failures` commit status:
|
||||
|
||||
- CI passing: the PR is added to the merge queue.
|
||||
- CI unfinished (pending or missing status): the bot enables [Auto Merge], which queues the PR once required checks succeed.
|
||||
Note that if CI later fails, nothing happens until it is fixed and passes.
|
||||
- CI already failing (`error`/`failure` status): the bot does not enable Auto Merge, because it would never trigger, and fixing CI requires a new push that invalidates the merge command.
|
||||
A fresh `@NixOS/nixpkgs-merge-bot merge` comment is needed once CI is green again.
|
||||
|
||||
### Approving merge bot changes
|
||||
|
||||
@@ -104,3 +114,4 @@ This script can also be run locally to print basic test cases.
|
||||
[@NixOS/nixpkgs-ci]: https://github.com/orgs/NixOS/teams/nixpkgs-ci
|
||||
[@NixOS/nixpkgs-core]: https://github.com/orgs/NixOS/teams/nixpkgs-core
|
||||
[RFC 172]: https://github.com/NixOS/rfcs/pull/172
|
||||
[Auto Merge]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request
|
||||
|
||||
@@ -206,20 +206,8 @@ module.exports = async ({ github, context, core, dry }) => {
|
||||
|
||||
const maintainers = await getMaintainerMap(pull_request.base.ref)
|
||||
|
||||
const merge_bot_eligible = await handleMerge({
|
||||
github,
|
||||
context,
|
||||
core,
|
||||
log,
|
||||
dry,
|
||||
pull_request,
|
||||
events,
|
||||
maintainers,
|
||||
getTeamMembers,
|
||||
getUser,
|
||||
})
|
||||
|
||||
// Check for any human reviews other than the PR author, GitHub actions and other GitHub apps.
|
||||
// `commit { oid }` is needed by handleMerge to verify approvals are against the current head.
|
||||
const reviews = (
|
||||
await github.graphql(
|
||||
`query($owner: String!, $repo: String!, $pr: Int!) {
|
||||
@@ -231,6 +219,7 @@ module.exports = async ({ github, context, core, dry }) => {
|
||||
reviews(first: 100) {
|
||||
nodes {
|
||||
state
|
||||
commit { oid }
|
||||
user: author {
|
||||
# Only get users, no bots
|
||||
... on User {
|
||||
@@ -266,6 +255,20 @@ module.exports = async ({ github, context, core, dry }) => {
|
||||
r.user.id !== pull_request.user?.id,
|
||||
)
|
||||
|
||||
const merge_bot_eligible = await handleMerge({
|
||||
github,
|
||||
context,
|
||||
core,
|
||||
log,
|
||||
dry,
|
||||
pull_request,
|
||||
events,
|
||||
reviews,
|
||||
maintainers,
|
||||
getTeamMembers,
|
||||
getUser,
|
||||
})
|
||||
|
||||
const approvals = new Set(
|
||||
reviews
|
||||
.filter((review) => review.state === 'APPROVED')
|
||||
|
||||
@@ -2,11 +2,11 @@ const { classify } = require('../supportedBranches.js')
|
||||
|
||||
function runChecklist({
|
||||
committers,
|
||||
events,
|
||||
files,
|
||||
pull_request,
|
||||
log,
|
||||
maintainers,
|
||||
reviews,
|
||||
user,
|
||||
userIsMaintainer,
|
||||
}) {
|
||||
@@ -27,18 +27,35 @@ function runChecklist({
|
||||
.reduce((acc, cur) => acc?.intersection(cur) ?? cur)
|
||||
|
||||
const approvals = new Set(
|
||||
events
|
||||
reviews
|
||||
.filter(
|
||||
({ event, state, commit_id }) =>
|
||||
event === 'reviewed' &&
|
||||
state === 'approved' &&
|
||||
({ state, commit }) =>
|
||||
state === 'APPROVED' &&
|
||||
// Only approvals for the current head SHA count, otherwise authors could push
|
||||
// bad code between the approval and the merge.
|
||||
commit_id === pull_request.head.sha,
|
||||
commit?.oid === pull_request.head.sha,
|
||||
)
|
||||
.map(({ user }) => user?.id)
|
||||
// Some users have been deleted, so filter these out.
|
||||
.filter(Boolean),
|
||||
.map(({ user }) => user.id),
|
||||
)
|
||||
|
||||
// A "changes requested" review from a committer blocks both the merge queue and
|
||||
// auto-merge, even if it was made on an older commit (unlike approvals, GitHub does
|
||||
// not auto-dismiss changes-requested reviews on push). For each committer, take their
|
||||
// latest actionable review; if it's CHANGES_REQUESTED, they're blocking the PR.
|
||||
// Dismissed reviews surface as DISMISSED and comment-only follow-ups as COMMENTED, so
|
||||
// both are skipped naturally — the prior actionable review still stands until the
|
||||
// committer explicitly approves or requests changes again.
|
||||
const committerReviewState = new Map()
|
||||
for (const { user, state } of reviews) {
|
||||
if (
|
||||
committers.has(user.id) &&
|
||||
['APPROVED', 'CHANGES_REQUESTED'].includes(state)
|
||||
) {
|
||||
committerReviewState.set(user.id, state)
|
||||
}
|
||||
}
|
||||
const noBlockingReviews = !Array.from(committerReviewState.values()).includes(
|
||||
'CHANGES_REQUESTED',
|
||||
)
|
||||
|
||||
const checklist = {
|
||||
@@ -57,6 +74,11 @@ function runChecklist({
|
||||
pull_request.user.login === 'r-ryantm',
|
||||
},
|
||||
'PR is not a draft': !pull_request.draft,
|
||||
// CI state is intentionally *not* a checklist item: auto-merge exists precisely to
|
||||
// cover unfinished CI, and an already-failed CI is reported via the merge message
|
||||
// (see merge() below) rather than a blanket refusal.
|
||||
'PR is not blocked by a "changes requested" review from a [committer](https://github.com/orgs/NixOS/teams/nixpkgs-committers).':
|
||||
noBlockingReviews,
|
||||
}
|
||||
|
||||
if (user) {
|
||||
@@ -123,6 +145,7 @@ async function handleMerge({
|
||||
dry,
|
||||
pull_request,
|
||||
events,
|
||||
reviews,
|
||||
maintainers,
|
||||
getTeamMembers,
|
||||
getUser,
|
||||
@@ -148,6 +171,14 @@ async function handleMerge({
|
||||
// including an early exit when the first non-by-name file is found.
|
||||
if (files.length >= 100) return false
|
||||
|
||||
const noPrFailuresState = (
|
||||
await github.rest.repos.listCommitStatusesForRef({
|
||||
...context.repo,
|
||||
ref: pull_request.head.sha,
|
||||
per_page: 100,
|
||||
})
|
||||
).data.find(({ context }) => context === 'no PR failures')?.state
|
||||
|
||||
// Only look through comments *after* the latest (force) push.
|
||||
const lastPush = events.findLastIndex(
|
||||
({ event, sha, commit_id }) =>
|
||||
@@ -173,10 +204,12 @@ async function handleMerge({
|
||||
)),
|
||||
)
|
||||
|
||||
// Returns `{ reaction, messages }`: the reaction to leave on the merge comment and the
|
||||
// lines to append to the bot's reply. Throws only on an unexpected API error.
|
||||
async function merge() {
|
||||
if (dry) {
|
||||
core.info(`Merging #${pull_number}... (dry)`)
|
||||
return ['Merge completed (dry)']
|
||||
return { reaction: 'ROCKET', messages: ['Merge completed (dry)'] }
|
||||
}
|
||||
|
||||
// Using GraphQL mutations instead of the REST /merge endpoint, because the latter
|
||||
@@ -197,16 +230,37 @@ async function handleMerge({
|
||||
{ node_id: pull_request.node_id, sha: pull_request.head.sha },
|
||||
)
|
||||
log('merge', 'Queued for merge')
|
||||
return [
|
||||
`:heavy_check_mark: [Queued](${resp.enqueuePullRequest.mergeQueueEntry.mergeQueue.url}) for merge (#306934)`,
|
||||
]
|
||||
return {
|
||||
reaction: 'ROCKET',
|
||||
messages: [
|
||||
`:heavy_check_mark: [Queued](${resp.enqueuePullRequest.mergeQueueEntry.mergeQueue.url}) for merge (#306934)`,
|
||||
],
|
||||
}
|
||||
} catch (e) {
|
||||
log('Enqueuing failed', e.response.errors[0].message)
|
||||
}
|
||||
|
||||
// If required status checks are not satisfied, yet, the above will fail. In this case
|
||||
// we can enable auto-merge. We could also only use auto-merge, but this often gets
|
||||
// stuck for no apparent reason.
|
||||
// Enqueuing fails when the required status checks are not satisfied, yet. If CI has
|
||||
// already failed, enabling auto-merge would be pointless: it would never fire, and
|
||||
// fixing CI requires a new push, which invalidates this merge command anyway (we only
|
||||
// act on comments after the latest push). So we don't enable auto-merge and instead
|
||||
// ask for a fresh command once CI is green again.
|
||||
if (['error', 'failure'].includes(noPrFailuresState)) {
|
||||
log('merge', 'CI has failed, not enabling auto-merge')
|
||||
return {
|
||||
reaction: 'THUMBS_DOWN',
|
||||
messages: [
|
||||
':x: Pull Request could not be merged: CI has failed (#305350).',
|
||||
'',
|
||||
'> [!TIP]',
|
||||
'> PRs cannot be merged while CI is failing.',
|
||||
'> Once CI is passing, comment `@NixOS/nixpkgs-merge-bot merge` again.',
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
// CI has not finished yet, so we enable auto-merge. We could also only use auto-merge,
|
||||
// but this often gets stuck for no apparent reason.
|
||||
try {
|
||||
await github.graphql(
|
||||
`mutation($node_id: ID!, $sha: GitObjectID) {
|
||||
@@ -219,12 +273,17 @@ async function handleMerge({
|
||||
{ node_id: pull_request.node_id, sha: pull_request.head.sha },
|
||||
)
|
||||
log('merge', 'Auto-merge enabled')
|
||||
return [
|
||||
`:heavy_check_mark: Enabled Auto Merge (#306934)`,
|
||||
'',
|
||||
'> [!TIP]',
|
||||
'> Sometimes GitHub gets stuck after enabling Auto Merge. In this case, leaving another approval should trigger the merge.',
|
||||
]
|
||||
return {
|
||||
reaction: 'ROCKET',
|
||||
messages: [
|
||||
`:heavy_check_mark: Enabled Auto Merge (#306934)`,
|
||||
'',
|
||||
'> [!TIP]',
|
||||
'> [Auto Merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request) will queue this PR once required CI checks succeed.',
|
||||
'> If CI fails instead, fixing it needs a new push, which disables Auto Merge and invalidates this command — comment `@NixOS/nixpkgs-merge-bot merge` again once CI is green.',
|
||||
'> If GitHub gets stuck even though CI passed (it sometimes does), leaving another approval should kick off the merge.',
|
||||
],
|
||||
}
|
||||
} catch (e) {
|
||||
log('Auto Merge failed', e.response.errors[0].message)
|
||||
throw new Error(e.response.errors[0].message)
|
||||
@@ -267,11 +326,11 @@ async function handleMerge({
|
||||
|
||||
const { result, eligible, checklist } = runChecklist({
|
||||
committers,
|
||||
events,
|
||||
files,
|
||||
pull_request,
|
||||
log,
|
||||
maintainers,
|
||||
reviews,
|
||||
user: comment.user,
|
||||
userIsMaintainer: await isMaintainer(comment.user.login),
|
||||
})
|
||||
@@ -308,10 +367,12 @@ async function handleMerge({
|
||||
}
|
||||
|
||||
if (result) {
|
||||
await react('ROCKET')
|
||||
try {
|
||||
body.push(...(await merge()))
|
||||
const { reaction, messages } = await merge()
|
||||
await react(reaction)
|
||||
body.push(...messages)
|
||||
} catch (e) {
|
||||
await react('THUMBS_DOWN')
|
||||
// Remove the HTML comment with node_id reference to allow retrying this merge on the next run.
|
||||
body.shift()
|
||||
body.push(`:x: Merge failed with: ${e} (#371492)`)
|
||||
@@ -336,11 +397,11 @@ async function handleMerge({
|
||||
|
||||
const { result } = runChecklist({
|
||||
committers,
|
||||
events,
|
||||
files,
|
||||
pull_request,
|
||||
log,
|
||||
maintainers,
|
||||
reviews,
|
||||
})
|
||||
|
||||
// Returns a boolean, which indicates whether the PR is merge-bot eligible in principle.
|
||||
|
||||
@@ -1323,6 +1323,17 @@ lib.mapAttrs mkLicense (
|
||||
fullName = "Qwt exception 1.0";
|
||||
};
|
||||
|
||||
reticulum = {
|
||||
# The Reticulum License restricts certain fields of use, notably systems
|
||||
# intended to harm human beings and AI/ML training datasets. Such usage
|
||||
# restrictions are incompatible with the Open Source Definition
|
||||
# (https://opensource.org/osd), in particular "No Discrimination Against
|
||||
# Fields of Endeavor".
|
||||
free = false;
|
||||
fullName = "Reticulum License";
|
||||
url = "https://reticulum.network/license";
|
||||
};
|
||||
|
||||
ruby = {
|
||||
spdxId = "Ruby";
|
||||
fullName = "Ruby License";
|
||||
|
||||
@@ -84,6 +84,7 @@ in
|
||||
StateDirectory = "zigbee2mqtt";
|
||||
StateDirectoryMode = "0700";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 10;
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
|
||||
@@ -9,16 +9,19 @@ let
|
||||
cfg = config.services.journald.gateway;
|
||||
|
||||
cliArgs = lib.cli.toCommandLineShellGNU { } {
|
||||
# If either of these are null / false, they are not passed in the command-line
|
||||
# If either of these are false, they are not passed in the command-line
|
||||
inherit (cfg)
|
||||
cert
|
||||
key
|
||||
trust
|
||||
system
|
||||
user
|
||||
merge
|
||||
;
|
||||
};
|
||||
|
||||
tlsOptionRemovedMessage = ''
|
||||
systemd in Nixpkgs is built without GnuTLS, so systemd-journal-gatewayd
|
||||
cannot serve HTTPS. Use a reverse proxy (such as nginx) to terminate TLS
|
||||
in front of the gateway if you need encrypted access.
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
@@ -26,6 +29,9 @@ in
|
||||
[ "services" "journald" "enableHttpGateway" ]
|
||||
[ "services" "journald" "gateway" "enable" ]
|
||||
)
|
||||
(lib.mkRemovedOptionModule [ "services" "journald" "gateway" "cert" ] tlsOptionRemovedMessage)
|
||||
(lib.mkRemovedOptionModule [ "services" "journald" "gateway" "key" ] tlsOptionRemovedMessage)
|
||||
(lib.mkRemovedOptionModule [ "services" "journald" "gateway" "trust" ] tlsOptionRemovedMessage)
|
||||
];
|
||||
|
||||
meta.maintainers = [ ];
|
||||
@@ -40,47 +46,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
cert = lib.mkOption {
|
||||
default = null;
|
||||
type = with lib.types; nullOr str;
|
||||
description = ''
|
||||
The path to a file or `AF_UNIX` stream socket to read the server
|
||||
certificate from.
|
||||
|
||||
The certificate must be in PEM format. This option switches
|
||||
`systemd-journal-gatewayd` into HTTPS mode and must be used together
|
||||
with {option}`services.journald.gateway.key`.
|
||||
'';
|
||||
};
|
||||
|
||||
key = lib.mkOption {
|
||||
default = null;
|
||||
type = with lib.types; nullOr str;
|
||||
description = ''
|
||||
Specify the path to a file or `AF_UNIX` stream socket to read the
|
||||
secret server key corresponding to the certificate specified with
|
||||
{option}`services.journald.gateway.cert` from.
|
||||
|
||||
The key must be in PEM format.
|
||||
|
||||
This key should not be world-readable, and must be readably by the
|
||||
`systemd-journal-gateway` user.
|
||||
'';
|
||||
};
|
||||
|
||||
trust = lib.mkOption {
|
||||
default = null;
|
||||
type = with lib.types; nullOr str;
|
||||
description = ''
|
||||
Specify the path to a file or `AF_UNIX` stream socket to read a CA
|
||||
certificate from.
|
||||
|
||||
The certificate must be in PEM format.
|
||||
|
||||
Setting this option enforces client certificate checking.
|
||||
'';
|
||||
};
|
||||
|
||||
system = lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
|
||||
@@ -12,25 +12,30 @@ let
|
||||
cliArgs = lib.cli.toCommandLineShellGNU { } {
|
||||
inherit (cfg) output;
|
||||
# "-3" specifies the file descriptor from the .socket unit.
|
||||
"listen-${cfg.listen}" = "-3";
|
||||
"listen-http" = "-3";
|
||||
};
|
||||
|
||||
tlsOptionRemovedMessage = ''
|
||||
systemd in Nixpkgs is built without GnuTLS, so systemd-journal-remote
|
||||
cannot accept HTTPS connections or validate client certificates. Use a
|
||||
reverse proxy (such as nginx) to terminate TLS in front of journal-remote
|
||||
if you need encrypted ingestion.
|
||||
'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ ];
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [
|
||||
"services"
|
||||
"journald"
|
||||
"remote"
|
||||
"listen"
|
||||
] tlsOptionRemovedMessage)
|
||||
];
|
||||
|
||||
options.services.journald.remote = {
|
||||
enable = lib.mkEnableOption "receiving systemd journals from the network";
|
||||
|
||||
listen = lib.mkOption {
|
||||
default = "https";
|
||||
type = lib.types.enum [
|
||||
"https"
|
||||
"http"
|
||||
];
|
||||
description = ''
|
||||
Which protocol to listen to.
|
||||
'';
|
||||
};
|
||||
|
||||
output = lib.mkOption {
|
||||
default = "/var/log/journal/remote/";
|
||||
type = lib.types.str;
|
||||
@@ -50,10 +55,6 @@ in
|
||||
type = lib.types.port;
|
||||
description = ''
|
||||
The port to listen to.
|
||||
|
||||
Note that this option is used only if
|
||||
{option}`services.journald.upload.listen` is configured to be either
|
||||
"https" or "http".
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -92,55 +93,28 @@ in
|
||||
one output journal file is used.
|
||||
'';
|
||||
};
|
||||
|
||||
ServerKeyFile = lib.mkOption {
|
||||
default = "/etc/ssl/private/journal-remote.pem";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
A path to a SSL secret key file in PEM format.
|
||||
|
||||
Note that due to security reasons, `systemd-journal-remote` will
|
||||
refuse files from the world-readable `/nix/store`. This file
|
||||
should be readable by the "" user.
|
||||
|
||||
This option can be used with `listen = "https"`. If the path
|
||||
refers to an `AF_UNIX` stream socket in the file system a
|
||||
connection is made to it and the key read from it.
|
||||
'';
|
||||
};
|
||||
|
||||
ServerCertificateFile = lib.mkOption {
|
||||
default = "/etc/ssl/certs/journal-remote.pem";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
A path to a SSL certificate file in PEM format.
|
||||
|
||||
This option can be used with `listen = "https"`. If the path
|
||||
refers to an `AF_UNIX` stream socket in the file system a
|
||||
connection is made to it and the certificate read from it.
|
||||
'';
|
||||
};
|
||||
|
||||
TrustedCertificateFile = lib.mkOption {
|
||||
default = "/etc/ssl/ca/trusted.pem";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
A path to a SSL CA certificate file in PEM format, or `all`.
|
||||
|
||||
If `all` is set, then client certificate checking will be
|
||||
disabled.
|
||||
|
||||
This option can be used with `listen = "https"`. If the path
|
||||
refers to an `AF_UNIX` stream socket in the file system a
|
||||
connection is made to it and the certificate read from it.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
map
|
||||
(key: {
|
||||
assertion = !(cfg.settings ? Remote.${key});
|
||||
message = ''
|
||||
The option definition `services.journald.remote.settings.Remote.${key}'
|
||||
no longer has any effect; please remove it.
|
||||
${tlsOptionRemovedMessage}
|
||||
'';
|
||||
})
|
||||
[
|
||||
"ServerKeyFile"
|
||||
"ServerCertificateFile"
|
||||
"TrustedCertificateFile"
|
||||
];
|
||||
|
||||
systemd.additionalUpstreamSystemUnits = [
|
||||
"systemd-journal-remote.service"
|
||||
"systemd-journal-remote.socket"
|
||||
|
||||
@@ -20,6 +20,13 @@ from typing import Any
|
||||
|
||||
Attrs = dict[str, Any]
|
||||
|
||||
# mkcomposefs hard-limits inline content to LCFS_INLINE_CONTENT_MAX (5000 bytes).
|
||||
# We stay a bit below that. Files larger than this are served from the basedir
|
||||
# data-only lower layer via an overlay redirect; files at or below it are
|
||||
# embedded directly into the erofs metadata image, avoiding the redirect
|
||||
# indirection at read time and keeping the basedir empty in the common case.
|
||||
INLINE_CONTENT_MAX = 4096
|
||||
|
||||
|
||||
class FileType(Enum):
|
||||
"""The filetype as defined by the `st_mode` stat field in octal
|
||||
@@ -55,12 +62,14 @@ class ComposefsPath:
|
||||
mode: str,
|
||||
payload: str,
|
||||
path: str | None = None,
|
||||
content: str = "-",
|
||||
):
|
||||
if path is None:
|
||||
path = attrs["target"]
|
||||
self.path = path
|
||||
self.size = size
|
||||
self.filetype = filetype
|
||||
self.content = content
|
||||
|
||||
match len(mode):
|
||||
case 3 | 4:
|
||||
@@ -95,6 +104,43 @@ def eprint(*args: Any, **kwargs: Any) -> None:
|
||||
print(*args, **kwargs, file=sys.stderr)
|
||||
|
||||
|
||||
# Bytes that may appear unescaped in a composefs-dump field. Everything else
|
||||
# is encoded as \xHH. See composefs-dump(5).
|
||||
_DUMP_SHORT_ESCAPES: dict[int, str] = {
|
||||
ord("\\"): r"\\",
|
||||
ord("\n"): r"\n",
|
||||
ord("\r"): r"\r",
|
||||
ord("\t"): r"\t",
|
||||
}
|
||||
|
||||
|
||||
def escape_dump_field(data: bytes) -> str:
|
||||
"""Escape raw bytes for use as a composefs-dump field.
|
||||
|
||||
The dump format separates fields by a single space and lines by a single
|
||||
newline, uses '\\' as the escape character and reserves '-' for unset
|
||||
optional fields, so all of these (plus non-printable bytes and '=') must
|
||||
be escaped.
|
||||
"""
|
||||
if data == b"":
|
||||
# An empty CONTENT field would be indistinguishable from two spaces
|
||||
# between PAYLOAD and DIGEST; callers must emit '-' for size-0 files
|
||||
# instead of inlining them.
|
||||
raise ValueError("cannot escape empty content; emit '-' instead")
|
||||
if data == b"-":
|
||||
# A bare '-' means "unset"; escape it so it round-trips as content.
|
||||
return r"\x2d"
|
||||
out: list[str] = []
|
||||
for b in data:
|
||||
if b in _DUMP_SHORT_ESCAPES:
|
||||
out.append(_DUMP_SHORT_ESCAPES[b])
|
||||
elif b in (ord(" "), ord("=")) or not (0x20 <= b <= 0x7E):
|
||||
out.append(f"\\x{b:02x}")
|
||||
else:
|
||||
out.append(chr(b))
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def normalize_path(path: str) -> str:
|
||||
return str("/" + os.path.normpath(path).lstrip("/"))
|
||||
|
||||
@@ -201,14 +247,37 @@ def main() -> None:
|
||||
payload=source,
|
||||
)
|
||||
else:
|
||||
composefs_path = ComposefsPath(
|
||||
attrs,
|
||||
size=os.stat(source).st_size,
|
||||
filetype=FileType.file,
|
||||
mode=mode,
|
||||
# payload needs to be relative path in this case
|
||||
payload=target.lstrip("/"),
|
||||
)
|
||||
size = os.stat(source).st_size
|
||||
if size <= INLINE_CONTENT_MAX:
|
||||
# Inline small files directly into the erofs image so they
|
||||
# do not need to be served from the basedir data layer via
|
||||
# an overlay redirect. Empty files need neither payload nor
|
||||
# content; mkcomposefs treats size=0 as an empty inline
|
||||
# file.
|
||||
if size > 0:
|
||||
with open(source, "rb") as fh:
|
||||
raw = fh.read()
|
||||
content = escape_dump_field(raw)
|
||||
size = len(raw)
|
||||
else:
|
||||
content = "-"
|
||||
composefs_path = ComposefsPath(
|
||||
attrs,
|
||||
size=size,
|
||||
filetype=FileType.file,
|
||||
mode=mode,
|
||||
payload="-",
|
||||
content=content,
|
||||
)
|
||||
else:
|
||||
composefs_path = ComposefsPath(
|
||||
attrs,
|
||||
size=size,
|
||||
filetype=FileType.file,
|
||||
mode=mode,
|
||||
# payload needs to be relative path in this case
|
||||
payload=target.lstrip("/"),
|
||||
)
|
||||
paths[target] = composefs_path
|
||||
add_leading_directories(target, attrs, paths)
|
||||
|
||||
|
||||
@@ -69,6 +69,22 @@ let
|
||||
|
||||
etcHardlinks = lib.filter (f: f.mode != "symlink" && f.mode != "direct-symlink") etc';
|
||||
|
||||
# Regular files at or below this size are inlined into the erofs metadata
|
||||
# image (see build-composefs-dump.py) and therefore do not need to be
|
||||
# shipped in the basedir data-only lower layer. Keep this in sync with
|
||||
# INLINE_CONTENT_MAX in build-composefs-dump.py.
|
||||
etcInlineContentMax = 4096;
|
||||
|
||||
# Entries whose content we can prove at eval time will be served directly
|
||||
# from the metadata image (inlined, or empty). Excluding them here keeps
|
||||
# their source paths out of the basedir build script, so changing a small
|
||||
# text-backed /etc file does not rebuild etc-lowerdir. Entries backed by
|
||||
# `source` (size unknown at eval time) are kept and filtered at build time
|
||||
# below.
|
||||
isInlinedAtEvalTime = f: f.text != null && lib.stringLength f.text <= etcInlineContentMax;
|
||||
|
||||
etcBasedirEntries = lib.filter (f: !isInlinedAtEvalTime f) etcHardlinks;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -371,6 +387,18 @@ in
|
||||
src="$1"
|
||||
target="$2"
|
||||
|
||||
if [[ -f "$src" ]]; then
|
||||
# Small regular files are inlined into the erofs metadata image by
|
||||
# build-composefs-dump.py and served directly from there, so we do
|
||||
# not need a copy in the basedir data layer. Keep the size check in
|
||||
# sync with INLINE_CONTENT_MAX in build-composefs-dump.py. Empty
|
||||
# files need no backing copy either.
|
||||
size=$(stat --dereference --format=%s "$src")
|
||||
if (( size <= ${toString etcInlineContentMax} )); then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$out/$(dirname "$target")"
|
||||
cp "$src" "$out/$target"
|
||||
}
|
||||
@@ -384,7 +412,7 @@ in
|
||||
"${etcEntry.source}"
|
||||
etcEntry.target
|
||||
]
|
||||
) etcHardlinks}
|
||||
) etcBasedirEntries}
|
||||
'';
|
||||
|
||||
system.build.etcMetadataImage =
|
||||
|
||||
@@ -20,6 +20,23 @@
|
||||
text = "foo";
|
||||
mode = "0300";
|
||||
};
|
||||
# Small regular file: inlined into the metadata erofs image.
|
||||
inlinetest = {
|
||||
text = "inline-content\n";
|
||||
mode = "0640";
|
||||
};
|
||||
# Empty regular file: served directly from the metadata erofs image
|
||||
# without payload or content.
|
||||
emptytest = {
|
||||
text = "";
|
||||
mode = "0644";
|
||||
};
|
||||
# Large regular file (>4096 bytes): served from the basedir data layer
|
||||
# via overlay redirect, not inlined.
|
||||
bigfile = {
|
||||
text = lib.strings.replicate 5000 "a";
|
||||
mode = "0644";
|
||||
};
|
||||
};
|
||||
|
||||
# Prerequisites
|
||||
@@ -63,6 +80,23 @@
|
||||
machine.succeed("stat --format '%F' /etc/modetest | tee /dev/stderr | grep -q 'regular file'")
|
||||
machine.succeed("stat --format '%F' /etc/modetest2 | tee /dev/stderr | grep -q 'regular file'")
|
||||
|
||||
with subtest("small regular files are inlined into the metadata image"):
|
||||
assert machine.succeed("cat /etc/inlinetest") == "inline-content\n"
|
||||
machine.succeed("stat --format '%a' /etc/inlinetest | tee /dev/stderr | grep -Eq '^640$'")
|
||||
# Inlined files are stored in the metadata erofs image, not redirected
|
||||
# to the basedir data layer, so they carry no overlay redirect xattr.
|
||||
machine.fail("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/inlinetest")
|
||||
|
||||
with subtest("empty regular files are served from the metadata image"):
|
||||
assert machine.succeed("cat /etc/emptytest") == ""
|
||||
machine.succeed("stat --format '%F %s %a' /etc/emptytest | tee /dev/stderr | grep -Eq '^regular empty file 0 644$'")
|
||||
machine.fail("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/emptytest")
|
||||
|
||||
with subtest("large regular files are served from the basedir"):
|
||||
assert machine.succeed("wc -c < /etc/bigfile").strip() == "5000"
|
||||
assert machine.succeed("head -c 10 /etc/bigfile") == "aaaaaaaaaa"
|
||||
machine.succeed("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/bigfile")
|
||||
|
||||
with subtest("direct symlinks point to the target without indirection"):
|
||||
assert machine.succeed("readlink -n /etc/localtime") == "/etc/zoneinfo/Utc"
|
||||
|
||||
|
||||
@@ -20,6 +20,23 @@
|
||||
text = "foo";
|
||||
mode = "0300";
|
||||
};
|
||||
# Small regular file: inlined into the metadata erofs image.
|
||||
inlinetest = {
|
||||
text = "inline-content\n";
|
||||
mode = "0640";
|
||||
};
|
||||
# Empty regular file: served directly from the metadata erofs image
|
||||
# without payload or content.
|
||||
emptytest = {
|
||||
text = "";
|
||||
mode = "0644";
|
||||
};
|
||||
# Large regular file (>4096 bytes): served from the basedir data layer
|
||||
# via overlay redirect, not inlined.
|
||||
bigfile = {
|
||||
text = lib.strings.replicate 5000 "a";
|
||||
mode = "0644";
|
||||
};
|
||||
};
|
||||
|
||||
# Prerequisites
|
||||
@@ -66,6 +83,23 @@
|
||||
machine.succeed("test -d /.rw-etc/upper/nixos")
|
||||
print(machine.succeed("getfattr -h -d -m 'trusted.overlay' /.rw-etc/upper/nixos 2>&1 || true"))
|
||||
|
||||
with subtest("small regular files are inlined into the metadata image"):
|
||||
assert machine.succeed("cat /etc/inlinetest") == "inline-content\n"
|
||||
machine.succeed("stat --format '%a' /etc/inlinetest | tee /dev/stderr | grep -Eq '^640$'")
|
||||
# Inlined files are stored in the metadata erofs image, not redirected
|
||||
# to the basedir data layer, so they carry no overlay redirect xattr.
|
||||
machine.fail("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/inlinetest")
|
||||
|
||||
with subtest("empty regular files are served from the metadata image"):
|
||||
assert machine.succeed("cat /etc/emptytest") == ""
|
||||
machine.succeed("stat --format '%F %s %a' /etc/emptytest | tee /dev/stderr | grep -Eq '^regular empty file 0 644$'")
|
||||
machine.fail("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/emptytest")
|
||||
|
||||
with subtest("large regular files are served from the basedir"):
|
||||
assert machine.succeed("wc -c < /etc/bigfile").strip() == "5000"
|
||||
assert machine.succeed("head -c 10 /etc/bigfile") == "aaaaaaaaaa"
|
||||
machine.succeed("getfattr -h -n trusted.overlay.redirect /run/nixos-etc-metadata/bigfile")
|
||||
|
||||
with subtest("switching to the same generation"):
|
||||
machine.succeed("/run/current-system/bin/switch-to-configuration test")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "systemd-journal-gateway";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
@@ -7,64 +7,21 @@
|
||||
];
|
||||
};
|
||||
|
||||
# Named client for coherence with the systemd-journal-upload test, and for
|
||||
# certificate validation
|
||||
# Named client for coherence with the systemd-journal-upload test.
|
||||
nodes.client = {
|
||||
services.journald.gateway = {
|
||||
enable = true;
|
||||
cert = "/run/secrets/client/cert.pem";
|
||||
key = "/run/secrets/client/key.pem";
|
||||
trust = "/run/secrets/ca.cert.pem";
|
||||
};
|
||||
services.journald.gateway.enable = true;
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import json
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
tmpdir_o = tempfile.TemporaryDirectory()
|
||||
tmpdir = tmpdir_o.name
|
||||
|
||||
def generate_pems(domain: str):
|
||||
subprocess.run(
|
||||
[
|
||||
"${pkgs.minica}/bin/minica",
|
||||
"--ca-key=ca.key.pem",
|
||||
"--ca-cert=ca.cert.pem",
|
||||
f"--domains={domain}",
|
||||
],
|
||||
cwd=str(tmpdir),
|
||||
)
|
||||
|
||||
with subtest("Creating keys and certificates"):
|
||||
generate_pems("server")
|
||||
generate_pems("client")
|
||||
|
||||
client.wait_for_unit("multi-user.target")
|
||||
|
||||
def copy_pem(file: str):
|
||||
client.copy_from_host(source=f"{tmpdir}/{file}", target=f"/run/secrets/{file}")
|
||||
client.succeed(f"chmod 600 /run/secrets/{file} && chown systemd-journal-gateway /run/secrets/{file}")
|
||||
|
||||
with subtest("Copying keys and certificates"):
|
||||
client.succeed("mkdir -p /run/secrets/{client,server}")
|
||||
copy_pem("server/cert.pem")
|
||||
copy_pem("server/key.pem")
|
||||
copy_pem("client/cert.pem")
|
||||
copy_pem("client/key.pem")
|
||||
copy_pem("ca.cert.pem")
|
||||
|
||||
client.wait_for_unit("multi-user.target")
|
||||
|
||||
curl = '${pkgs.curl}/bin/curl'
|
||||
accept_json = '--header "Accept: application/json"'
|
||||
cacert = '--cacert /run/secrets/ca.cert.pem'
|
||||
cert = '--cert /run/secrets/server/cert.pem'
|
||||
key = '--key /run/secrets/server/key.pem'
|
||||
base_url = 'https://client:19531'
|
||||
base_url = 'http://client:19531'
|
||||
|
||||
curl_cli = f"{curl} {accept_json} {cacert} {cert} {key} --fail"
|
||||
curl_cli = f"{curl} {accept_json} --fail"
|
||||
|
||||
machine_info = client.succeed(f"{curl_cli} {base_url}/machine")
|
||||
assert json.loads(machine_info)["hostname"] == "client", "wrong machine name"
|
||||
@@ -78,11 +35,8 @@
|
||||
|
||||
client.succeed(f"systemd-cat --identifier={identifier} <<< '{message}'")
|
||||
|
||||
# max-time is a workaround against a bug in systemd-journal-gatewayd where
|
||||
# if TLS is enabled, the connection is never closed. Since it will timeout,
|
||||
# we ignore the return code.
|
||||
entries = client.succeed(
|
||||
f"{curl_cli} --max-time 5 {base_url}/entries?SYSLOG_IDENTIFIER={identifier} || true"
|
||||
f"{curl_cli} {base_url}/entries?SYSLOG_IDENTIFIER={identifier}"
|
||||
)
|
||||
|
||||
# Number of entries should be only 1
|
||||
|
||||
@@ -7,48 +7,84 @@
|
||||
];
|
||||
};
|
||||
|
||||
# systemd in Nixpkgs is built without GnuTLS, so systemd-journal-remote
|
||||
# cannot terminate TLS itself. We put nginx in front of it with mutual TLS
|
||||
# and have systemd-journal-upload (which uses curl+openssl) talk HTTPS to
|
||||
# nginx. This exercises both the recommended migration path and verifies
|
||||
# that journal-upload's TLS support still works.
|
||||
nodes.server =
|
||||
{ nodes, ... }:
|
||||
{ lib, nodes, ... }:
|
||||
{
|
||||
|
||||
services.journald.remote = {
|
||||
enable = true;
|
||||
listen = "http";
|
||||
settings.Remote = {
|
||||
ServerCertificateFile = "/run/secrets/sever.cert.pem";
|
||||
ServerKeyFile = "/run/secrets/sever.key.pem";
|
||||
TrustedCertificateFile = "/run/secrets/ca.cert.pem";
|
||||
Seal = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ nodes.server.services.journald.remote.port ];
|
||||
};
|
||||
# Keep journal-remote loopback-only; only nginx is exposed to the network.
|
||||
systemd.sockets.systemd-journal-remote.listenStreams = lib.mkForce [
|
||||
""
|
||||
"127.0.0.1:${toString nodes.server.services.journald.remote.port}"
|
||||
];
|
||||
|
||||
nodes.client =
|
||||
{ lib, nodes, ... }:
|
||||
{
|
||||
services.journald.upload = {
|
||||
virtualisation.credentials = {
|
||||
"ca.cert.pem".source = "./ca.cert.pem";
|
||||
"server.cert.pem".source = "./server.cert.pem";
|
||||
"server.key.pem".source = "./server.key.pem";
|
||||
};
|
||||
systemd.services.nginx.serviceConfig.ImportCredential = [
|
||||
"server.cert.pem"
|
||||
"server.key.pem"
|
||||
"ca.cert.pem"
|
||||
];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
settings.Upload = {
|
||||
URL = "http://server:${toString nodes.server.services.journald.remote.port}";
|
||||
ServerCertificateFile = "/run/secrets/client.cert.pem";
|
||||
ServerKeyFile = "/run/secrets/client.key.pem";
|
||||
TrustedCertificateFile = "/run/secrets/ca.cert.pem";
|
||||
virtualHosts."server" = {
|
||||
onlySSL = true;
|
||||
http2 = false;
|
||||
sslCertificate = "/run/credentials/nginx.service/server.cert.pem";
|
||||
sslCertificateKey = "/run/credentials/nginx.service/server.key.pem";
|
||||
extraConfig = ''
|
||||
ssl_client_certificate /run/credentials/nginx.service/ca.cert.pem;
|
||||
ssl_verify_client on;
|
||||
'';
|
||||
locations."/".proxyPass = "http://127.0.0.1:${toString nodes.server.services.journald.remote.port}";
|
||||
};
|
||||
};
|
||||
|
||||
# Wait for the PEMs to arrive
|
||||
systemd.services.systemd-journal-upload.wantedBy = lib.mkForce [ ];
|
||||
systemd.paths.systemd-journal-upload = {
|
||||
wantedBy = [ "default.target" ];
|
||||
# This file must be copied last
|
||||
pathConfig.PathExists = [ "/run/secrets/ca.cert.pem" ];
|
||||
networking.firewall.allowedTCPPorts = [ 443 ];
|
||||
};
|
||||
|
||||
nodes.client =
|
||||
{ lib, ... }:
|
||||
{
|
||||
virtualisation.credentials = {
|
||||
"ca.cert.pem".source = "./ca.cert.pem";
|
||||
"client.cert.pem".source = "./client.cert.pem";
|
||||
"client.key.pem".source = "./client.key.pem";
|
||||
};
|
||||
systemd.services.systemd-journal-upload.serviceConfig.ImportCredential = [
|
||||
"client.cert.pem"
|
||||
"client.key.pem"
|
||||
"ca.cert.pem"
|
||||
];
|
||||
services.journald.upload = {
|
||||
enable = true;
|
||||
settings.Upload = {
|
||||
URL = "https://server:443";
|
||||
ServerCertificateFile = "/run/credentials/systemd-journal-upload.service/client.cert.pem";
|
||||
ServerKeyFile = "/run/credentials/systemd-journal-upload.service/client.key.pem";
|
||||
TrustedCertificateFile = "/run/credentials/systemd-journal-upload.service/ca.cert.pem";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import subprocess
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
tmpdir_o = tempfile.TemporaryDirectory()
|
||||
tmpdir = tmpdir_o.name
|
||||
@@ -68,33 +104,17 @@
|
||||
generate_pems("server")
|
||||
generate_pems("client")
|
||||
|
||||
server.wait_for_unit("multi-user.target")
|
||||
client.wait_for_unit("multi-user.target")
|
||||
|
||||
def copy_pems(machine: BaseMachine, domain: str):
|
||||
machine.succeed("mkdir /run/secrets")
|
||||
machine.copy_from_host(
|
||||
source=f"{tmpdir}/{domain}/cert.pem",
|
||||
target=f"/run/secrets/{domain}.cert.pem",
|
||||
)
|
||||
machine.copy_from_host(
|
||||
source=f"{tmpdir}/{domain}/key.pem",
|
||||
target=f"/run/secrets/{domain}.key.pem",
|
||||
)
|
||||
# Should be last
|
||||
machine.copy_from_host(
|
||||
source=f"{tmpdir}/ca.cert.pem",
|
||||
target="/run/secrets/ca.cert.pem",
|
||||
)
|
||||
shutil.copy(f"{tmpdir}/{domain}/cert.pem", machine.state_dir / f"{domain}.cert.pem")
|
||||
shutil.copy(f"{tmpdir}/{domain}/key.pem", machine.state_dir / f"{domain}.key.pem")
|
||||
shutil.copy(f"{tmpdir}/ca.cert.pem", machine.state_dir / "ca.cert.pem")
|
||||
|
||||
with subtest("Copying keys and certificates"):
|
||||
copy_pems(server, "server")
|
||||
copy_pems(client, "client")
|
||||
|
||||
server.wait_for_unit("nginx.service")
|
||||
client.wait_for_unit("systemd-journal-upload.service")
|
||||
# The journal upload should have started the remote service, triggered by
|
||||
# the .socket unit
|
||||
server.wait_for_unit("systemd-journal-remote.service")
|
||||
|
||||
identifier = "nixos-test"
|
||||
message = "Hello from NixOS test infrastructure"
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "gambatte";
|
||||
version = "0-unstable-2026-06-14";
|
||||
version = "0-unstable-2026-06-19";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libretro";
|
||||
repo = "gambatte-libretro";
|
||||
rev = "e99e1bd9b91de67ac12c77c3679c85447c26e8c8";
|
||||
hash = "sha256-i5Bx5MstvwwKfH/Lmlj3jheQsbHP2BU8Ecpp3m5D8HA=";
|
||||
rev = "4832d33cc3427ee0a1c1b9065339dd18ff57370d";
|
||||
hash = "sha256-qn3zYecSmQjQV1f0Aw6+zVEQttMSHsrNQuMFbsDyKC8=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "swanstation";
|
||||
version = "0-unstable-2026-06-14";
|
||||
version = "0-unstable-2026-06-25";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libretro";
|
||||
repo = "swanstation";
|
||||
rev = "93b213d805591c4f1488339c4a16f0b4cb68d44a";
|
||||
hash = "sha256-l4HhejwOKE/bk9HFf2mDTDqc223m6UofTIF+BgMIDEw=";
|
||||
rev = "32e5654cb4ff17db3e950250a677767906fa3cf8";
|
||||
hash = "sha256-l4Vb1kSuoqMJC4gn+S61zuePZaYvJ/nmVyoFOlsCTBM=";
|
||||
};
|
||||
|
||||
extraNativeBuildInputs = [ cmake ];
|
||||
|
||||
@@ -204,7 +204,7 @@ stdenv.mkDerivation {
|
||||
ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
|
||||
|
||||
mkdir -p "$out/share"
|
||||
for f in '${chromium.browser}'/share/*; do
|
||||
for f in '${chromiumWV}'/share/*; do
|
||||
ln -s -t "$out/share/" "$f"
|
||||
done
|
||||
'';
|
||||
|
||||
@@ -420,16 +420,16 @@ in
|
||||
|
||||
docker_29 =
|
||||
let
|
||||
version = "29.5.3";
|
||||
version = "29.6.0";
|
||||
in
|
||||
callPackage dockerGen {
|
||||
inherit version;
|
||||
cliRev = "v${version}";
|
||||
cliHash = "sha256-ZYfBWNVp7w8ZKdRA6bmDVQV4UEp+t8lWehInvtfysxM=";
|
||||
cliHash = "sha256-2JTiqvrIYhpwbEgU+5DnmlHpaf8Re1vYPkySs93sKZU=";
|
||||
mobyRev = "docker-v${version}";
|
||||
mobyHash = "sha256-D+XjHsKUFgMBCQsFI825JIGHEQmDt3NQCwpTdu6XSc8=";
|
||||
runcRev = "v1.3.5";
|
||||
runcHash = "sha256-Swphxbu/OLkUrfRjLMZIVGwYb7AN0xHdyxm0ysAVam0=";
|
||||
mobyHash = "sha256-xr3+RZANLP4IkLv26/7znXnTCOm/5Gm7k6WBaOlZfQk=";
|
||||
runcRev = "v1.3.6";
|
||||
runcHash = "sha256-cBMYZOElWHQ4OkF2NlYJSZrlW4833WD8CRJRkkXeKJc=";
|
||||
containerdRev = "v2.2.4";
|
||||
containerdHash = "sha256-F0lw7zh4V9JlFQGkE4RNT1VLX8WWLgZAAvbP12jnRMw=";
|
||||
tiniRev = "369448a167e8b3da4ca5bca0b3307500c3371828";
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/vrc-get-gui/Tauri.toml b/vrc-get-gui/Tauri.toml
|
||||
index cd180da8..66a81aa9 100644
|
||||
--- a/vrc-get-gui/Tauri.toml
|
||||
+++ b/vrc-get-gui/Tauri.toml
|
||||
@@ -34,8 +34,6 @@ icon = [
|
||||
resources = []
|
||||
publisher = "anatawa12"
|
||||
|
||||
-createUpdaterArtifacts = "v1Compatible" # remove if ci # we do not generate updater artifacts in CI
|
||||
-
|
||||
[[bundle.fileAssociations]]
|
||||
# note: for macOS we directory use info.plist for registering file association.
|
||||
description = "ALCOM Project Template"
|
||||
@@ -17,25 +17,18 @@
|
||||
webkitgtk_4_1,
|
||||
}:
|
||||
let
|
||||
subdir = "vrc-get-gui";
|
||||
in
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "alcom";
|
||||
version = "1.1.5";
|
||||
|
||||
version = "1.1.6";
|
||||
src = fetchFromGitHub {
|
||||
owner = "vrc-get";
|
||||
repo = "vrc-get";
|
||||
tag = "gui-v${version}";
|
||||
hash = "sha256-xucU8nXskniHOiuwrtVoZM2FIKNKU45i4DNo6iLjZvM=";
|
||||
tag = "gui-v${finalAttrs.version}";
|
||||
hash = "sha256-TpVHE3e3dMdBOtPVKomKvg5tQf42QWik18k5oVD2Hms=";
|
||||
};
|
||||
|
||||
subdir = "vrc-get-gui";
|
||||
in
|
||||
rustPlatform.buildRustPackage {
|
||||
inherit pname version src;
|
||||
|
||||
patches = [
|
||||
./disable-updater-artifacts.patch
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
cargo-about
|
||||
cargo-tauri.hook
|
||||
@@ -55,13 +48,15 @@ rustPlatform.buildRustPackage {
|
||||
webkitgtk_4_1
|
||||
];
|
||||
|
||||
cargoHash = "sha256-MeCx3BoEXckMZfecyBcwwVE8+6V9Di6ULkIhUvUFZIA=";
|
||||
cargoHash = "sha256-J8vCr+B4J3ZqxkkNk+x0jr52qNJJYfBJe2oyLf0GLsc=";
|
||||
buildFeatures = [ "no-self-updater" ];
|
||||
buildAndTestSubdir = subdir;
|
||||
|
||||
npmDeps = fetchNpmDeps {
|
||||
inherit src;
|
||||
sourceRoot = "${src.name}/${subdir}";
|
||||
hash = "sha256-snXOfAtanLPhQNo0mg/r8UUXJua2X+52t7+7QS1vOkI=";
|
||||
name = "${finalAttrs.pname}-${finalAttrs.version}-npm-deps";
|
||||
inherit (finalAttrs) src;
|
||||
sourceRoot = "${finalAttrs.src.name}/${subdir}";
|
||||
hash = "sha256-VyA2c2659Kg1DjLmmtvSAivltdraSBNArIu1XGENGmQ=";
|
||||
};
|
||||
npmRoot = subdir;
|
||||
|
||||
@@ -69,8 +64,11 @@ rustPlatform.buildRustPackage {
|
||||
description = "Experimental GUI application to manage VRChat Unity Projects";
|
||||
homepage = "https://github.com/vrc-get/vrc-get";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ Scrumplex ];
|
||||
maintainers = with lib.maintainers; [
|
||||
Scrumplex
|
||||
ImSapphire
|
||||
];
|
||||
broken = stdenv.hostPlatform.isDarwin;
|
||||
mainProgram = "ALCOM";
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -27,13 +27,13 @@ let
|
||||
in
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "atlauncher";
|
||||
version = "3.4.40.4";
|
||||
version = "3.4.41.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ATLauncher";
|
||||
repo = "ATLauncher";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-pRYXzFUbVXYwD7edhBoVcVo/QDo6QSJJQd58Hf3rBGo=";
|
||||
hash = "sha256-mowPK9wsX87LHLt17Wmn97H2TRICXuwGKC2p2MBXr4Y=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "carapace";
|
||||
version = "1.6.3";
|
||||
version = "1.7.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "carapace-sh";
|
||||
repo = "carapace-bin";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-k6fWtwDTNc2qcr9ryL7wMVy744fiP8NrLqm4crVr+EI=";
|
||||
hash = "sha256-wIRBz1WjN4Sy5hkRvAWHWRrtcTpVdY7BOLp1KF8UC5A=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-5AqoM16M5pPfRYxqa72LrHJRRatK2qnZK3pQIoFXG9g=";
|
||||
vendorHash = "sha256-s6Wq7+2S7hxAhU2OJ8TCkSG5H9dJjwlDy5G02Uqnzm4=";
|
||||
|
||||
proxyVendor = true;
|
||||
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
buildNpmPackage (finalAttrs: {
|
||||
pname = "claude-agent-acp";
|
||||
version = "0.45.1";
|
||||
version = "0.52.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "agentclientprotocol";
|
||||
repo = "claude-agent-acp";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-NiDsm0tcK80CQyG8zn974ErwDP0hXXOHbCLX9BpErKY=";
|
||||
hash = "sha256-w8lrc/4cW7QZNDMvq663eas7Dl4tnya4JCM9xkLF8S8=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-WB+ZMtDmqZrEg8/k9peCm+EbKvZc8qfOV33STT1vj8k=";
|
||||
npmDepsHash = "sha256-czNQInLxK/DMFViJWa15PGOU61qnqm0wNwFqjTH3Z+k=";
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ./generic.nix {
|
||||
version = "26.3.13.31-lts";
|
||||
rev = "27ae4e9fe0e3f97f012b3be293caf42a60d08747";
|
||||
hash = "sha256-NTts2SiaQ+B+iPCAPLF4fLQmZ9/0Gp2FFu/E0aXfCMc=";
|
||||
version = "26.3.15.4-lts";
|
||||
rev = "3c767441a1ed9b5828b94806d87a25501d1f7364";
|
||||
hash = "sha256-7vhnUjmZtHm2v8a7w2gBxgFz153kbbUi94oy04vheLo=";
|
||||
lts = true;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "element-desktop";
|
||||
version = "1.12.21";
|
||||
version = "1.12.22";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "element-hq";
|
||||
repo = "element-web";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-wtMmfNZptCMPp3j6dicEM/80otz20UBQw+HXb8EXJl0=";
|
||||
hash = "sha256-TtC4KUnaKy/gmh5CbkPTWKCFjdeKvt8esFt3awdkA/g=";
|
||||
};
|
||||
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
@@ -47,7 +47,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
;
|
||||
inherit pnpm;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-OPpJ5XJ0YeidvlT88JwQIKXxbQ40l0xdVH/9uT3La2M=";
|
||||
hash = "sha256-Cxc2/NpOpkXavDvBgaU6Douud7AO06jt1KjuaLnZh8M=";
|
||||
};
|
||||
|
||||
env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
|
||||
|
||||
@@ -25,13 +25,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "element-web";
|
||||
version = "1.12.21";
|
||||
version = "1.12.22";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "element-hq";
|
||||
repo = "element-web";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-wtMmfNZptCMPp3j6dicEM/80otz20UBQw+HXb8EXJl0=";
|
||||
hash = "sha256-TtC4KUnaKy/gmh5CbkPTWKCFjdeKvt8esFt3awdkA/g=";
|
||||
};
|
||||
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
@@ -39,7 +39,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
inherit (finalAttrs) version src;
|
||||
inherit pnpm;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-OPpJ5XJ0YeidvlT88JwQIKXxbQ40l0xdVH/9uT3La2M=";
|
||||
hash = "sha256-Cxc2/NpOpkXavDvBgaU6Douud7AO06jt1KjuaLnZh8M=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "geeqie";
|
||||
version = "2.7";
|
||||
version = "2.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "BestImageViewer";
|
||||
repo = "geeqie";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-yCY9ltm21cD3NnC2hDZ3O+2UZYgop4TLHC0djPF3Lo0=";
|
||||
hash = "sha256-90e+f95RIv2FZUFrfr6e7MhsQ8Xnve+Ie+uPyc87FRE=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
}:
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "go-hass-agent";
|
||||
version = "14.12.0";
|
||||
version = "14.14.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "joshuar";
|
||||
repo = "go-hass-agent";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-KQRM6b6BtCkY+raJoshOYOoKwOzRwzFTLFnHTY6hCSY=";
|
||||
hash = "sha256-s5kzxzyfNGK57MtusjEjcm0Gn75Wu8vfwJEIaVz7m20=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-WsxxT1hCpGt7YAcbp2NDVLPl4lFLHlZraiKUePoQwNU=";
|
||||
vendorHash = "sha256-ZiLYnEcugciobjAchzJZNQrE3G11ehf3vi6cIMxZiTQ=";
|
||||
|
||||
npmDeps = fetchNpmDeps {
|
||||
inherit (finalAttrs) src;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "grafana";
|
||||
version = "13.0.2";
|
||||
version = "13.0.3";
|
||||
|
||||
subPackages = [
|
||||
"pkg/cmd/grafana"
|
||||
@@ -33,7 +33,7 @@ buildGoModule (finalAttrs: {
|
||||
owner = "grafana";
|
||||
repo = "grafana";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-knalINdJPFrvj6HNxWPV6wu6TSkrRvgkZjOnECOsWwU=";
|
||||
hash = "sha256-HOTArHAoqhyKiqJf0Py2JMiMBloSgNDnVPDcKWlnY3I=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
@@ -55,12 +55,12 @@ buildGoModule (finalAttrs: {
|
||||
# Since this is not a dependency attribute the buildPackages has to be specified.
|
||||
offlineCache = buildPackages.yarn-berry_4-fetcher.fetchYarnBerryDeps {
|
||||
inherit (finalAttrs) src missingHashes patches;
|
||||
hash = "sha256-NXDXmed2TsMQS99breDt0Ky6X2ZyuWkJ5KyKz5Apkt8=";
|
||||
hash = "sha256-pYuNW74ghHmBVzRcfXTXROjxo2FmsxmkTUbJpEFMkow=";
|
||||
};
|
||||
|
||||
disallowedRequisites = [ finalAttrs.offlineCache ];
|
||||
|
||||
vendorHash = "sha256-rFGwtplr+n0qgIulycNQ5L/lh4ZFoHCrYeIfbb+e/h4=";
|
||||
vendorHash = "sha256-dVu95a6xc7fEK3epeY0ZzF4IUT+WhozAmSDicYoIL4A=";
|
||||
|
||||
# Grafana seems to just set it to the latest version available
|
||||
# nowadays.
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
{
|
||||
rustPlatform,
|
||||
lib,
|
||||
config,
|
||||
fetchFromSourcehut,
|
||||
pam,
|
||||
scdoc,
|
||||
installShellFiles,
|
||||
nix-update-script,
|
||||
# legacy passthrus
|
||||
gtkgreet,
|
||||
qtgreet,
|
||||
regreet,
|
||||
tuigreet,
|
||||
wlgreet,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
@@ -45,26 +38,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
installManPage man/*
|
||||
'';
|
||||
|
||||
# Added 2025-07-23. To be deleted on 26.05
|
||||
passthru =
|
||||
let
|
||||
warnPassthru = name: lib.warnOnInstantiate "`greetd.${name}` was renamed to `${name}`";
|
||||
in
|
||||
lib.mapAttrs warnPassthru (
|
||||
lib.optionalAttrs config.allowAliases {
|
||||
inherit
|
||||
gtkgreet
|
||||
qtgreet
|
||||
regreet
|
||||
tuigreet
|
||||
wlgreet
|
||||
;
|
||||
greetd = finalAttrs.finalPackage;
|
||||
}
|
||||
)
|
||||
// {
|
||||
updateScript = nix-update-script { };
|
||||
};
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Minimal and flexible login manager daemon";
|
||||
@@ -75,7 +49,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
'';
|
||||
homepage = "https://sr.ht/~kennylevinsen/greetd/";
|
||||
mainProgram = "greetd";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
license = lib.licenses.gpl3Only;
|
||||
maintainers = [ ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
meta = {
|
||||
description = "GTK based greeter for greetd, to be run under cage or similar";
|
||||
homepage = "https://git.sr.ht/~kennylevinsen/gtkgreet";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
license = lib.licenses.gpl3Only;
|
||||
maintainers = [ ];
|
||||
platforms = lib.platforms.linux;
|
||||
mainProgram = "gtkgreet";
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
fetchFromGitHub,
|
||||
pkg-config,
|
||||
cmake,
|
||||
makeWrapper,
|
||||
makeBinaryWrapper,
|
||||
ninja,
|
||||
perl,
|
||||
perlPackages,
|
||||
brotli,
|
||||
openssl,
|
||||
libcap,
|
||||
libuv,
|
||||
wslay,
|
||||
zlib,
|
||||
withBrotli ? true,
|
||||
brotli,
|
||||
withMruby ? true,
|
||||
bison,
|
||||
ruby,
|
||||
@@ -24,13 +25,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "h2o";
|
||||
version = "2.3.0-rolling-2026-06-24";
|
||||
version = "2.3.0-rolling-2026-06-25";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "h2o";
|
||||
repo = "h2o";
|
||||
rev = "66fcbfed806d7645577e4e78e4d536d38379764d";
|
||||
hash = "sha256-RzQHDHihcD+ife1CBCGliytrkt8eYVdL8AHdaYp3CFQ=";
|
||||
rev = "58a9a054300a09235df52954101a49573762e0fc";
|
||||
hash = "sha256-TofY3JzWM4XNiMqna5KnmtBJETndJ/YY0sFY/0X99GA=";
|
||||
};
|
||||
|
||||
outputs = [
|
||||
@@ -43,10 +44,11 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
cmake
|
||||
makeWrapper
|
||||
makeBinaryWrapper
|
||||
ninja
|
||||
perlPackages.JSON
|
||||
]
|
||||
++ lib.optional withBrotli brotli
|
||||
++ lib.optionals withMruby [
|
||||
bison
|
||||
ruby
|
||||
@@ -61,9 +63,11 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
perl
|
||||
zlib
|
||||
wslay
|
||||
];
|
||||
]
|
||||
++ lib.optional withBrotli brotli;
|
||||
|
||||
cmakeFlags = [
|
||||
"-DWITH_BROTLI=${if withBrotli then "ON" else "OFF"}"
|
||||
"-DWITH_MRUBY=${if withMruby then "ON" else "OFF"}"
|
||||
];
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "jfbview";
|
||||
version = "0.6.1";
|
||||
version = "0.7.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jichu4n";
|
||||
repo = "jfbview";
|
||||
tag = finalAttrs.version;
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-7iyDfMuGAXXLyDNz0d4jEQ+KfJ/LyUu4v1n0GcOKeEc=";
|
||||
hash = "sha256-X52FBg4Jgb80OETu29p4lcWpT+OSRz1xfhw+IkFZr+I=";
|
||||
};
|
||||
|
||||
__structuredAttrs = true;
|
||||
|
||||
@@ -12,18 +12,18 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "kluctl";
|
||||
version = "2.27.0";
|
||||
version = "2.28.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kluctl";
|
||||
repo = "kluctl";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-m/bfZb+sp0gqxfMdBr/gAOxfYHdrPwKRcJAqprkAkQE=";
|
||||
hash = "sha256-Adh2n8aE+DEBY1MC4laVPDdr5dq6FKSMEFLjbs74D4c=";
|
||||
};
|
||||
|
||||
subPackages = [ "cmd" ];
|
||||
|
||||
vendorHash = "sha256-TKMMMZ+8bv5kKgrHIp3CXmt4tpi5VejPpXv/oiX4M3c=";
|
||||
vendorHash = "sha256-cQJRU3vL5wJ0dgYMtN4qFdvJyp367I4N7GM6PhRvW0I=";
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "matterircd";
|
||||
version = "0.29.0";
|
||||
version = "0.30.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "42wim";
|
||||
repo = "matterircd";
|
||||
rev = "v${finalAttrs.version}";
|
||||
sha256 = "sha256-7pOhUeUT95nk6kk03xAaIYHgXwr09m6LSbib2YSi1Ck=";
|
||||
sha256 = "sha256-W00q5bRzCXl9R56xGol1bWYeW5w5MUpcoraKVaKimyk=";
|
||||
};
|
||||
|
||||
vendorHash = null;
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "miller";
|
||||
version = "6.18.1";
|
||||
version = "6.19.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "johnkerl";
|
||||
repo = "miller";
|
||||
rev = "v${finalAttrs.version}";
|
||||
sha256 = "sha256-pXxXUw956M5EUhL1TFtQp1JTXQwQK9qxp2vjBkozi/0=";
|
||||
sha256 = "sha256-kIhJ9wysaWnZNvaWaNE32FQOHFDNBtUl41d1Z45VFac=";
|
||||
};
|
||||
|
||||
outputs = [
|
||||
@@ -20,7 +20,7 @@ buildGoModule (finalAttrs: {
|
||||
"man"
|
||||
];
|
||||
|
||||
vendorHash = "sha256-ZnNEOVChF3kizfjti6Cgexvt/5UPIRQsyfUz8c03EKc=";
|
||||
vendorHash = "sha256-PzklwkT2Chs3z1UzLX9g9hpDGTHmyxfiT0igSntXPqo=";
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $man/share/man/man1
|
||||
|
||||
59
pkgs/by-name/pa/parla/package.nix
Normal file
59
pkgs/by-name/pa/parla/package.nix
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
deltachat-rpc-server,
|
||||
fetchFromGitHub,
|
||||
glib,
|
||||
gtk4,
|
||||
json-glib,
|
||||
lib,
|
||||
libadwaita,
|
||||
meson,
|
||||
ninja,
|
||||
nix-update-script,
|
||||
pkg-config,
|
||||
stdenv,
|
||||
vala,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "parla";
|
||||
version = "0.5.6";
|
||||
__structuredAttrs = true;
|
||||
strictDeps = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "trufae";
|
||||
repo = "parla";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-ZCIEjpsGh4WjzTRapoUoZTt5ld4K/SranfLIUWM0htk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
vala
|
||||
];
|
||||
|
||||
mesonFlags = [
|
||||
"-Drpc_server_path=${lib.getExe deltachat-rpc-server}"
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
glib
|
||||
gtk4
|
||||
json-glib
|
||||
libadwaita
|
||||
];
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
changelog = "https://github.com/trufae/parla/releases/tag/${finalAttrs.src.tag}";
|
||||
description = "Native Gnome DeltaChat client";
|
||||
homepage = "https://github.com/trufae/parla";
|
||||
license = lib.licenses.gpl3Only;
|
||||
mainProgram = "parla";
|
||||
maintainers = [ lib.maintainers.dotlambda ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
})
|
||||
@@ -19,13 +19,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "qlever";
|
||||
version = "0.5.47";
|
||||
version = "0.5.48";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ad-freiburg";
|
||||
repo = "qlever";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-sRV3OZTg9Q2Nvys0OgMbBGRqWPm+8P9zJD9rcaEEZ/Y=";
|
||||
hash = "sha256-CqrwsUXjM5VwsNkLDkXgT6ZfqFZIuz2oPKVqO4z2t3A=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "quarkus-cli";
|
||||
version = "3.36.1";
|
||||
version = "3.36.3";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/quarkusio/quarkus/releases/download/${finalAttrs.version}/quarkus-cli-${finalAttrs.version}.tar.gz";
|
||||
hash = "sha256-fhGWH8ksB0JzhQL8EWkKCFA+8EpY7EMsgnTMHqGFbQ0=";
|
||||
hash = "sha256-qb93KrBzoAe6Kt9GPH3jZ3jnBOnWxrY+d9FmYz5RM/c=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "redo";
|
||||
version = "1.4";
|
||||
version = "1.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jdebp";
|
||||
repo = "redo";
|
||||
rev = "91f5462339ef6373f9ac80902cfae2b614e2902b";
|
||||
hash = "sha256-cA8UN4aQnJ8VyMW3mDOIPna4Ucw1kp8CirZTDhSoCpU=";
|
||||
rev = "fb5088e1cc588134fd653809be038a4dbffe8f74";
|
||||
hash = "sha256-QFdTpSF0IdqkBtL0SRmKS9OetEk2UNeJlotw8IwMx48=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -21,17 +21,28 @@ stdenv.mkDerivation {
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
package/compile
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
package/export $out/
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/jdebp/redo";
|
||||
description = "System for building target files from source files";
|
||||
license = lib.licenses.bsd2;
|
||||
# https://github.com/jdebp/redo/blob/trunk/source/COPYING
|
||||
license =
|
||||
with lib.licenses;
|
||||
OR [
|
||||
bsd2 # for some reason BSD-2-Clause and FreeBSD, despite being synonyms, are listed separately
|
||||
isc
|
||||
mit
|
||||
];
|
||||
maintainers = [ ];
|
||||
mainProgram = "redo";
|
||||
platforms = lib.platforms.unix;
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "snx-rs";
|
||||
version = "6.1.1";
|
||||
version = "6.1.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ancwrd1";
|
||||
repo = "snx-rs";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-64xwXC8s7BY8fzwrmpoF2sNqkknUj2AHLZprnuM1Be8=";
|
||||
hash = "sha256-JhknaTqvd7Dsox38FH6mphbi+DPzVoyLlyAX6ZsqPkI=";
|
||||
};
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
@@ -49,7 +49,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
versionCheckHook
|
||||
];
|
||||
|
||||
cargoHash = "sha256-/SQBcItOANmqcCzZ5/uKcVYA9btDqzApHJRSNbDh/ws=";
|
||||
cargoHash = "sha256-lclSkg+WDRl3LQuzF4Q1+5zRT7UcnrasVvbcgd7wbxQ=";
|
||||
|
||||
doInstallCheck = true;
|
||||
versionCheckProgram = "${placeholder "out"}/bin/snx-rs";
|
||||
|
||||
@@ -37,7 +37,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
description = "Raw wayland greeter for greetd, to be run under sway or similar";
|
||||
mainProgram = "wlgreet";
|
||||
homepage = "https://git.sr.ht/~kennylevinsen/wlgreet";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
license = lib.licenses.gpl3Only;
|
||||
maintainers = [ ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
|
||||
@@ -1,45 +1,3 @@
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
{ python3Packages }:
|
||||
|
||||
let
|
||||
version = "2.6.3";
|
||||
src = fetchFromGitHub {
|
||||
owner = "Shoobx";
|
||||
repo = "xmldiff";
|
||||
rev = version;
|
||||
hash = "sha256-qn8gGultTSNKPUro6Ap4xJGcbpxV+lKgZFpKvyPdhtc=";
|
||||
};
|
||||
in
|
||||
python3.pkgs.buildPythonApplication {
|
||||
pname = "xmldiff";
|
||||
inherit version src;
|
||||
pyproject = true;
|
||||
|
||||
build-system = with python3.pkgs; [ setuptools ];
|
||||
|
||||
dependencies = with python3.pkgs; [
|
||||
lxml
|
||||
setuptools # pkg_resources is imported during runtime
|
||||
];
|
||||
|
||||
meta = {
|
||||
homepage = "https://xmldiff.readthedocs.io/en/stable/";
|
||||
description = "Library and command line utility for diffing xml";
|
||||
longDescription = ''
|
||||
xmldiff is a library and a command-line utility for making diffs out of
|
||||
XML. This may seem like something that doesn't need a dedicated utility,
|
||||
but change detection in hierarchical data is very different from change
|
||||
detection in flat data. XML type formats are also not only used for
|
||||
computer readable data, it is also often used as a format for hierarchical
|
||||
data that can be rendered into human readable formats. A traditional diff
|
||||
on such a format would tell you line by line the differences, but this
|
||||
would not be readable by a human. xmldiff provides tools to make human
|
||||
readable diffs in those situations.
|
||||
'';
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ anpryl ];
|
||||
};
|
||||
}
|
||||
python3Packages.toPythonApplication python3Packages.xmldiff
|
||||
|
||||
@@ -38,6 +38,11 @@ buildPythonPackage rec {
|
||||
url = "https://github.com/geigerzaehler/beets-alternatives/commit/84fdb0fa15225cce1e881b07bddcb52715677915.patch";
|
||||
hash = "sha256-rURvP7aNJ+I9bPjk43t8rYujOK1iUS1J4RFMAHfa5AU=";
|
||||
})
|
||||
# Fix for Beets 2.12; see https://github.com/geigerzaehler/beets-alternatives/pull/234
|
||||
(fetchpatch {
|
||||
url = "https://github.com/geigerzaehler/beets-alternatives/commit/e27772bb627d1b0763685d7add209d40987f2b95.patch";
|
||||
hash = "sha256-47HhaYWzHQakGlbUWdfG5qkfvbadbow1i+O74JnKPwM=";
|
||||
})
|
||||
];
|
||||
|
||||
build-system = [
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
fetchpatch2,
|
||||
buildPythonPackage,
|
||||
|
||||
# build-system
|
||||
poetry-core,
|
||||
uv-build,
|
||||
|
||||
# nativeBuildInputs
|
||||
beets-minimal,
|
||||
@@ -14,7 +13,6 @@
|
||||
pytestCheckHook,
|
||||
beets-audible,
|
||||
mediafile,
|
||||
pytest,
|
||||
reflink,
|
||||
toml,
|
||||
typeguard,
|
||||
@@ -23,31 +21,23 @@
|
||||
|
||||
buildPythonPackage (finalAttrs: {
|
||||
pname = "beets-filetote";
|
||||
version = "1.3.5";
|
||||
version = "1.3.6";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "gtronset";
|
||||
repo = "beets-filetote";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-qMHjcBrXkVG7U5a1E0yRwNgmg7XinRnK3gnV7jAZLTk=";
|
||||
hash = "sha256-ZrF9Z3Eaem8ZzNJgQoW45MvsNOCoLsd7l/yLQ2pldR0=";
|
||||
};
|
||||
# needed to keep beetsplug a namespace package, othwise other plugins will not be found
|
||||
# can be removed with next version
|
||||
patches = [
|
||||
(fetchpatch2 {
|
||||
url = "https://github.com/gtronset/beets-filetote/commit/762cf0c4b60b8f6b38cf39b027de4241f12cef37.patch?full_index=1";
|
||||
hash = "sha256-c7qIECcqwoV4ZOaA/8JYsM6Aym34peWPh7ZLWUxIYSI=";
|
||||
excludes = [ "CHANGELOG.md" ];
|
||||
})
|
||||
];
|
||||
|
||||
# https://github.com/gtronset/beets-filetote/issues/328
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml --replace-fail "poetry-core<2.0.0" "poetry-core"
|
||||
substituteInPlace pyproject.toml --replace-fail "uv_build>=0.11.21,<0.12" "uv-build"
|
||||
'';
|
||||
|
||||
build-system = [
|
||||
poetry-core
|
||||
uv-build
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -56,9 +46,6 @@ buildPythonPackage (finalAttrs: {
|
||||
|
||||
dependencies = [
|
||||
mediafile
|
||||
reflink
|
||||
toml
|
||||
typeguard
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
@@ -71,10 +58,12 @@ buildPythonPackage (finalAttrs: {
|
||||
writableTmpDirAsHomeHook
|
||||
];
|
||||
|
||||
pytestFlags = [
|
||||
# This is the same as:
|
||||
# -r fEs
|
||||
"-rfEs"
|
||||
disabledTestPaths = [
|
||||
# Tests fail for Beets 2.12.x, see:
|
||||
# https://github.com/gtronset/beets-filetote/issues/328
|
||||
"tests/test_exclude.py::TestExclude::test_exclude_strseq_of_filenames_by_string"
|
||||
"tests/test_exclude.py::TestExclude::test_exclude_strseq_of_filenames_by_list"
|
||||
"tests/test_printignored.py::TestPrintIgnored::test_print_ignored"
|
||||
];
|
||||
|
||||
meta = {
|
||||
|
||||
@@ -113,12 +113,12 @@
|
||||
|
||||
buildPythonPackage (finalAttrs: {
|
||||
pname = "beets";
|
||||
version = "2.11.0";
|
||||
version = "2.12.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "beetbox";
|
||||
repo = "beets";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-fi6D0P2GtEO41VL6UKAArRedZVxw97yqDUAoilktUho=";
|
||||
hash = "sha256-u2qoZ0/qWq9YUcwbOpsqtIjX5BZ2z2wj00X59Pf+/fk=";
|
||||
};
|
||||
pyproject = true;
|
||||
|
||||
|
||||
@@ -46,9 +46,7 @@ buildPythonPackage (finalAttrs: {
|
||||
description = "Lightweight Extensible Message Format for Reticulum";
|
||||
homepage = "https://github.com/markqvist/lxmf";
|
||||
changelog = "https://github.com/markqvist/LXMF/releases/tag/${finalAttrs.src.tag}";
|
||||
# Reticulum License
|
||||
# https://github.com/markqvist/LXMF/blob/master/LICENSE
|
||||
license = lib.licenses.unfree;
|
||||
license = lib.licenses.reticulum;
|
||||
maintainers = with lib.maintainers; [
|
||||
drupol
|
||||
fab
|
||||
|
||||
@@ -3,30 +3,38 @@
|
||||
stdenv,
|
||||
aiohttp,
|
||||
buildPythonPackage,
|
||||
ed25519,
|
||||
fetchFromGitHub,
|
||||
nats-server,
|
||||
nkeys,
|
||||
pynacl,
|
||||
pytest-asyncio,
|
||||
pytestCheckHook,
|
||||
setuptools,
|
||||
uv-build,
|
||||
uvloop,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
buildPythonPackage (finalAttrs: {
|
||||
pname = "nats-py";
|
||||
version = "2.12.0";
|
||||
version = "2.15.0";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "nats-io";
|
||||
repo = "nats.py";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-HQtoFyw3Gi/lIQFVrFvRtWWzHTY+TchZYKqTiHfUWFk=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-rs+C++g21dKZ6c7L5dJYqWSiv4J8qMGobW7R8icUfVw=";
|
||||
};
|
||||
|
||||
build-system = [ setuptools ];
|
||||
sourceRoot = "${finalAttrs.src.name}/nats";
|
||||
|
||||
dependencies = [ ed25519 ];
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail "uv_build>=0.9.28,<0.10.0" "uv_build"
|
||||
'';
|
||||
|
||||
build-system = [ uv-build ];
|
||||
|
||||
dependencies = [ pynacl ];
|
||||
|
||||
optional-dependencies = {
|
||||
aiohttp = [ aiohttp ];
|
||||
@@ -36,6 +44,7 @@ buildPythonPackage rec {
|
||||
|
||||
nativeCheckInputs = [
|
||||
nats-server
|
||||
pytest-asyncio
|
||||
pytestCheckHook
|
||||
uvloop
|
||||
];
|
||||
@@ -49,13 +58,11 @@ buildPythonPackage rec {
|
||||
"test_pull_subscribe_limits"
|
||||
"test_stream_management"
|
||||
"test_subscribe_no_echo"
|
||||
"test_rtt"
|
||||
# Tests fail on hydra, often Time-out
|
||||
"test_subscribe_iterate_next_msg"
|
||||
"test_ordered_consumer_larger_streams"
|
||||
"test_object_file_basics"
|
||||
# Should be safe to remove on next version upgrade (from 2.11.0)
|
||||
# https://github.com/nats-io/nats.py/pull/728
|
||||
"test_object_list"
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
"test_subscribe_iterate_next_msg"
|
||||
@@ -67,8 +74,8 @@ buildPythonPackage rec {
|
||||
meta = {
|
||||
description = "Python client for NATS.io";
|
||||
homepage = "https://github.com/nats-io/nats.py";
|
||||
changelog = "https://github.com/nats-io/nats.py/releases/tag/${src.tag}";
|
||||
changelog = "https://github.com/nats-io/nats.py/releases/tag/${finalAttrs.src.tag}";
|
||||
license = lib.licenses.asl20;
|
||||
maintainers = with lib.maintainers; [ fab ];
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -49,9 +49,7 @@ buildPythonPackage (finalAttrs: {
|
||||
description = "Cryptography-based networking stack for wide-area networks";
|
||||
homepage = "https://reticulum.network";
|
||||
changelog = "https://github.com/markqvist/Reticulum/blob/${finalAttrs.version}/Changelog.md";
|
||||
# Reticulum License
|
||||
# https://github.com/markqvist/Reticulum/blob/master/LICENSE
|
||||
license = lib.licenses.unfree;
|
||||
license = lib.licenses.reticulum;
|
||||
maintainers = with lib.maintainers; [
|
||||
drupol
|
||||
fab
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "sabctools";
|
||||
version = "9.4.1";
|
||||
version = "9.5.0";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
hash = "sha256-MU2vgWX7ojy5OYllEJTHrz9z7mvrJq3mrfRUM2jQ9ws=";
|
||||
hash = "sha256-x0+9GT/xs+EdX63qglTeuYE/z8cp/kOZmk6zd8MlAgQ=";
|
||||
};
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "wand";
|
||||
version = "0.7.1";
|
||||
version = "0.7.2";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "emcconville";
|
||||
repo = "wand";
|
||||
tag = version;
|
||||
hash = "sha256-SigXdX4sfw0nKYvIu/Jsoj+RBmcoHAGCFRA8t7gc+3s=";
|
||||
hash = "sha256-1ZkvJxlv47rQ2BOBnEWPczcjIM2muywemrxwY2ZN2UA=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -92,8 +92,7 @@ lib.makeOverridable (
|
||||
|
||||
# Whether to utilize the controversial import-from-derivation feature to parse the config
|
||||
allowImportFromDerivation ? false,
|
||||
# ignored
|
||||
features ? null,
|
||||
features ? { },
|
||||
lib ? lib_,
|
||||
stdenv ? stdenv_,
|
||||
}:
|
||||
@@ -514,6 +513,9 @@ lib.makeOverridable (
|
||||
inherit
|
||||
isZen
|
||||
withRust
|
||||
# Forwarded into passthru so features survive kernel.override() call chains
|
||||
# used by the NixOS module system (see boot.kernelPackages apply in kernel.nix).
|
||||
features
|
||||
;
|
||||
baseVersion = lib.head (lib.splitString "-rc" version);
|
||||
kernelOlder = lib.versionOlder baseVersion;
|
||||
|
||||
@@ -53,14 +53,14 @@ let
|
||||
in
|
||||
{
|
||||
nextcloud32 = generic {
|
||||
version = "32.0.11";
|
||||
hash = "sha256-vvIY5Yeczhy/0Q0gfVG1iiYPGQ1U/VcZkx7coMWdRiQ=";
|
||||
version = "32.0.12";
|
||||
hash = "sha256-rxWPclccjhXim8E2wjqSEYjOHVZoVQAK2U+JuAqPGAw=";
|
||||
packages = nextcloud32Packages;
|
||||
};
|
||||
|
||||
nextcloud33 = generic {
|
||||
version = "33.0.5";
|
||||
hash = "sha256-7Ua5HY2k4fAjTQGIslvulEj6LzAYh+WygBPmtUfW3Mo=";
|
||||
version = "33.0.6";
|
||||
hash = "sha256-eRghpVAplE3gQxnPyvysSujn71a0zR78JjG/MLedFt4=";
|
||||
packages = nextcloud33Packages;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"bookmarks": {
|
||||
"hash": "sha256-wf3t7qwxFAJBnPP3PYfa3Q/LrUaoONY47/So2w2fDww=",
|
||||
"url": "https://github.com/nextcloud/bookmarks/releases/download/v16.2.1/bookmarks-16.2.1.tar.gz",
|
||||
"version": "16.2.1",
|
||||
"hash": "sha256-8F+sNG/+M8Ed/q5dcxW95KS5ZBNsEeZNR0P2OIe/HqQ=",
|
||||
"url": "https://github.com/nextcloud/bookmarks/releases/download/v16.2.2/bookmarks-16.2.2.tar.gz",
|
||||
"version": "16.2.2",
|
||||
"description": "- 📂 Sort bookmarks into folders\n- 🏷 Add tags and personal notes\n- ☠ Find broken links and duplicates\n- 📲 Synchronize with all your browsers and devices\n- 📔 Store archived versions of your links in case they are depublished\n- 🔍 Full-text search on site contents\n- 👪 Share bookmarks with other users, groups and teams or via public links\n- ⚛ Generate RSS feeds of your collections\n- 📈 Stats on how often you access which links\n- 🔒 Automatic backups of your bookmarks collection\n- 💼 Built-in Dashboard widgets for frequent and recent links\n\nRequirements:\n - PHP extensions:\n - intl: *\n - mbstring: *\n - when using MySQL, use at least v8.0",
|
||||
"homepage": "https://github.com/nextcloud/bookmarks",
|
||||
"licenses": [
|
||||
@@ -30,9 +30,9 @@
|
||||
]
|
||||
},
|
||||
"collectives": {
|
||||
"hash": "sha256-ul8DRAOna5gCS9v0HhqFGdh/fFv6weG5x8ZMZjTLjhM=",
|
||||
"url": "https://github.com/nextcloud/collectives/releases/download/v4.4.1/collectives-4.4.1.tar.gz",
|
||||
"version": "4.4.1",
|
||||
"hash": "sha256-/MGwV78AAzsoAvI11JeodQsbiMZs1J58NzsGrEIv5EA=",
|
||||
"url": "https://github.com/nextcloud/collectives/releases/download/v4.4.2/collectives-4.4.2.tar.gz",
|
||||
"version": "4.4.2",
|
||||
"description": "Your space to collaboratively write and organize. Collectives is designed for groups and communities\nto structure shared knowledge and cultivate trust.\n\n* **👥 Non-hierarchical at its core**: Each collective is backed by a\n [Nextcloud Team](https://docs.nextcloud.com/server/latest/user_manual/en/groupware/contacts.html#teams) - its\n content is owned by the group, not a single user.\n* **📝 Collaborative page editing** thanks to the [Text app](https://github.com/nextcloud/text).\n* **🔤 Well-known [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax** for page formatting.\n* **🔎 Full-text search** to find content straight away.",
|
||||
"homepage": "https://collectives.cloud/",
|
||||
"licenses": [
|
||||
@@ -80,9 +80,9 @@
|
||||
]
|
||||
},
|
||||
"deck": {
|
||||
"hash": "sha256-t/9nWA3e2WBkMjevWMpzmhjBY8OaQS4nwryto4WJwtw=",
|
||||
"url": "https://github.com/nextcloud-releases/deck/releases/download/v1.16.6/deck-v1.16.6.tar.gz",
|
||||
"version": "1.16.6",
|
||||
"hash": "sha256-InDmm6aj8y8qfZ7i765XJIh4q0vsTlVtxA6n0E6rll0=",
|
||||
"url": "https://github.com/nextcloud-releases/deck/releases/download/v1.16.7/deck-v1.16.7.tar.gz",
|
||||
"version": "1.16.7",
|
||||
"description": "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized",
|
||||
"homepage": "https://github.com/nextcloud/deck",
|
||||
"licenses": [
|
||||
@@ -140,9 +140,9 @@
|
||||
]
|
||||
},
|
||||
"gpoddersync": {
|
||||
"hash": "sha256-9BcXVauZWFlmlXtnwdSo5xISbhhssa7ao5ulKpziOnU=",
|
||||
"url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.16.0/gpoddersync.tar.gz",
|
||||
"version": "3.16.0",
|
||||
"hash": "sha256-V4iJr1p5uqxdrvE50bjyNTiHdsZATewaBXKQ8Ma0dHg=",
|
||||
"url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.17.0/gpoddersync.tar.gz",
|
||||
"version": "3.17.0",
|
||||
"description": "Expose GPodder API to sync podcast consumer apps like AntennaPod",
|
||||
"homepage": "https://github.com/thrillfall/nextcloud-gpodder",
|
||||
"licenses": [
|
||||
@@ -210,9 +210,9 @@
|
||||
]
|
||||
},
|
||||
"mail": {
|
||||
"hash": "sha256-K6sJ3XJOq9MoO0lGgqn3iBYuDqqhOMeHWD1DLVY5HaU=",
|
||||
"url": "https://github.com/nextcloud-releases/mail/releases/download/v5.10.1/mail-v5.10.1.tar.gz",
|
||||
"version": "5.10.1",
|
||||
"hash": "sha256-GkLTk3Q1mSUGhU6lsNHmHGkwW6u4XoDCOj405vi8xuY=",
|
||||
"url": "https://github.com/nextcloud-releases/mail/releases/download/v5.10.3/mail-v5.10.3.tar.gz",
|
||||
"version": "5.10.3",
|
||||
"description": "**💌 A mail app for Nextcloud**\n\n- **🚀 Integration with other Nextcloud apps!** Currently Contacts, Calendar & Files – more to come.\n- **📥 Multiple mail accounts!** Personal and company account? No problem, and a nice unified inbox. Connect any IMAP account.\n- **🔒 Send & receive encrypted mails!** Using the great [Mailvelope](https://mailvelope.com) browser extension.\n- **🙈 We’re not reinventing the wheel!** Based on the great [Horde](https://www.horde.org) libraries.\n- **📬 Want to host your own mail server?** We do not have to reimplement this as you could set up [Mail-in-a-Box](https://mailinabox.email)!\n\n## Ethical AI Rating\n\n### Priority Inbox\n\nPositive:\n* The software for training and inferencing of this model is open source.\n* The model is created and trained on-premises based on the user's own data.\n* The training data is accessible to the user, making it possible to check or correct for bias or optimise the performance and CO2 usage.\n\n### Thread Summaries (opt-in)\n\n**Rating:** 🟢/🟡/🟠/🔴\n\nThe rating depends on the installed text processing backend. See [the rating overview](https://docs.nextcloud.com/server/latest/admin_manual/ai/index.html) for details.\n\nLearn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud.com/blog/nextcloud-ethical-ai-rating/).",
|
||||
"homepage": "https://github.com/nextcloud/mail#readme",
|
||||
"licenses": [
|
||||
@@ -290,9 +290,9 @@
|
||||
]
|
||||
},
|
||||
"onlyoffice": {
|
||||
"hash": "sha256-+phzZA410n9QQsba26OUf7XR+x24XMnmHamhqsqlcVo=",
|
||||
"url": "https://github.com/ONLYOFFICE/onlyoffice-nextcloud/releases/download/v9.14.0/onlyoffice.tar.gz",
|
||||
"version": "9.14.0",
|
||||
"hash": "sha256-sMgBVVAv6n6TlrvcndzRLc1xPJ6eA4hYBqDpiDabW1k=",
|
||||
"url": "https://github.com/ONLYOFFICE/onlyoffice-nextcloud/releases/download/v9.14.2/onlyoffice.tar.gz",
|
||||
"version": "9.14.2",
|
||||
"description": "The ONLYOFFICE app for Nextcloud brings powerful document editing and collaboration tools directly to your Nextcloud environment. With this integration, you can seamlessly create, edit, and co-author text documents, spreadsheets, presentations, and PDFs, as well as build and fill out PDF forms.\n\nCollaborate with your team in real time, make use of Track Changes, version history, comments, integrated chat, and more. Work together on files with federated cloud sharing. Flexible access permissions allow you to control who can view, edit, or comment, ensuring secure role-based collaboration tailored to your needs. Documents can also be protected with watermarks, password settings, and encryption for added security.\n\nThe app offers support for over 50 file formats, including DOCX, XLSX, PPTX, PDF, RTF, TXT, CSV, ODT, ODS, ODP, EPUB, FB2, HTML, HWP, HWPX, Pages, Numbers, Keynote, etc. Seamless desktop and mobile app integration means you'll have access to your Nextcloud files wherever you go.\n\nFurthermore, you can seamlessly connect any AI assistant, including local ones, directly to the editors to work faster and more efficient. This allows you to leverage various AI models for tasks like chatbot interactions, translations, OCR, and more.\n\nWhether you’re working with internal teams or external collaborators, the ONLYOFFICE app for Nextcloud enhances productivity, simplifies workflows, and ensures your files remain secure.",
|
||||
"homepage": "https://www.onlyoffice.com",
|
||||
"licenses": [
|
||||
@@ -410,9 +410,9 @@
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"hash": "sha256-I5QdNavgv74FSuXwFWNz/++LOY9Z8kNZhEKf2k118L8=",
|
||||
"url": "https://github.com/nextcloud/tasks/releases/download/v0.17.1/tasks.tar.gz",
|
||||
"version": "0.17.1",
|
||||
"hash": "sha256-nJFU65dthPRWd/SClKM/suZdYU3ic3QsIcXiPzUkQ6c=",
|
||||
"url": "https://github.com/nextcloud/tasks/releases/download/v0.18.0/tasks.tar.gz",
|
||||
"version": "0.18.0",
|
||||
"description": "Once enabled, a new Tasks menu will appear in your Nextcloud apps menu. From there you can add and delete tasks, edit their title, description, start and due dates and mark them as important. Tasks can be shared between users. Tasks can be synchronized using CalDav (each task list is linked to an Nextcloud calendar, to sync it to your local client: Thunderbird, Evolution, KDE Kontact, iCal … - just add the calendar as a remote calendar in your client). You can download your tasks as ICS files using the download button for each calendar.",
|
||||
"homepage": "https://github.com/nextcloud/tasks/",
|
||||
"licenses": [
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"bookmarks": {
|
||||
"hash": "sha256-wf3t7qwxFAJBnPP3PYfa3Q/LrUaoONY47/So2w2fDww=",
|
||||
"url": "https://github.com/nextcloud/bookmarks/releases/download/v16.2.1/bookmarks-16.2.1.tar.gz",
|
||||
"version": "16.2.1",
|
||||
"hash": "sha256-8F+sNG/+M8Ed/q5dcxW95KS5ZBNsEeZNR0P2OIe/HqQ=",
|
||||
"url": "https://github.com/nextcloud/bookmarks/releases/download/v16.2.2/bookmarks-16.2.2.tar.gz",
|
||||
"version": "16.2.2",
|
||||
"description": "- 📂 Sort bookmarks into folders\n- 🏷 Add tags and personal notes\n- ☠ Find broken links and duplicates\n- 📲 Synchronize with all your browsers and devices\n- 📔 Store archived versions of your links in case they are depublished\n- 🔍 Full-text search on site contents\n- 👪 Share bookmarks with other users, groups and teams or via public links\n- ⚛ Generate RSS feeds of your collections\n- 📈 Stats on how often you access which links\n- 🔒 Automatic backups of your bookmarks collection\n- 💼 Built-in Dashboard widgets for frequent and recent links\n\nRequirements:\n - PHP extensions:\n - intl: *\n - mbstring: *\n - when using MySQL, use at least v8.0",
|
||||
"homepage": "https://github.com/nextcloud/bookmarks",
|
||||
"licenses": [
|
||||
@@ -30,9 +30,9 @@
|
||||
]
|
||||
},
|
||||
"collectives": {
|
||||
"hash": "sha256-ul8DRAOna5gCS9v0HhqFGdh/fFv6weG5x8ZMZjTLjhM=",
|
||||
"url": "https://github.com/nextcloud/collectives/releases/download/v4.4.1/collectives-4.4.1.tar.gz",
|
||||
"version": "4.4.1",
|
||||
"hash": "sha256-/MGwV78AAzsoAvI11JeodQsbiMZs1J58NzsGrEIv5EA=",
|
||||
"url": "https://github.com/nextcloud/collectives/releases/download/v4.4.2/collectives-4.4.2.tar.gz",
|
||||
"version": "4.4.2",
|
||||
"description": "Your space to collaboratively write and organize. Collectives is designed for groups and communities\nto structure shared knowledge and cultivate trust.\n\n* **👥 Non-hierarchical at its core**: Each collective is backed by a\n [Nextcloud Team](https://docs.nextcloud.com/server/latest/user_manual/en/groupware/contacts.html#teams) - its\n content is owned by the group, not a single user.\n* **📝 Collaborative page editing** thanks to the [Text app](https://github.com/nextcloud/text).\n* **🔤 Well-known [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax** for page formatting.\n* **🔎 Full-text search** to find content straight away.",
|
||||
"homepage": "https://collectives.cloud/",
|
||||
"licenses": [
|
||||
@@ -80,9 +80,9 @@
|
||||
]
|
||||
},
|
||||
"deck": {
|
||||
"hash": "sha256-n0q700fSmqZ9tvsfSquXwh4ujtiBsW3wUaLnohu1MFg=",
|
||||
"url": "https://github.com/nextcloud-releases/deck/releases/download/v1.17.3/deck-v1.17.3.tar.gz",
|
||||
"version": "1.17.3",
|
||||
"hash": "sha256-DVSFbea5d0CL3bdpO8iOBYXKHSbXCQ8oLHi5YkPbCI4=",
|
||||
"url": "https://github.com/nextcloud-releases/deck/releases/download/v1.17.4/deck-v1.17.4.tar.gz",
|
||||
"version": "1.17.4",
|
||||
"description": "Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in Markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your Markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized",
|
||||
"homepage": "https://github.com/nextcloud/deck",
|
||||
"licenses": [
|
||||
@@ -90,13 +90,13 @@
|
||||
]
|
||||
},
|
||||
"end_to_end_encryption": {
|
||||
"hash": "sha256-+krBgynHh8sz6HZrpHsrRQRc/NedD6fW5jEwPrz8Vas=",
|
||||
"url": "https://github.com/nextcloud-releases/end_to_end_encryption/releases/download/v2.1.1/end_to_end_encryption-v2.1.1.tar.gz",
|
||||
"version": "2.1.1",
|
||||
"hash": "sha256-Z6MyXz//LNVy7Mt+yFbHIY5zGEMfsdwnAEDFsIcrs1M=",
|
||||
"url": "https://github.com/nextcloud-releases/end_to_end_encryption/releases/download/v2.2.0/end_to_end_encryption-v2.2.0.tar.gz",
|
||||
"version": "2.2.0",
|
||||
"description": "## **End-to-End Encryption**\n\n### For End Users\n\n**Protect your most sensitive files with strong encryption.**\n\nThe End-to-End Encryption app gives you complete control over your data privacy.\nWith this app, you can encrypt specific folders so that only you (and those you trust) can access their contents.\nYour files are encrypted on your device before they reach the server, ensuring that no one—not even the server administrator—can read them.\n\n**Benefits:**\n- 🔒 **True privacy**: Files are encrypted on your device and can only be decrypted by you\n- 📱 **Works across all platforms**: Fully supported on desktop, Android, iOS clients, and as you wish even in the browser\n- 🎯 **Selective encryption**: Choose which folders to encrypt\n- 🛡️ **Secure sharing**: Share encrypted files with other users or even secure public upload using the encrypted file drop\n\n---\n\n### For Administrators\n\n**Enterprise-ready end-to-end encryption infrastructure for your Nextcloud instance.**\n\nThis app provides all the necessary server-side APIs and infrastructure to enable End-to-End encryption (E2EE) for your users.\nIt ensures that encrypted data remains secure throughout its lifecycle on your server.\n\n**Technical highlights:**\n- 🔐 **Complete API suite**: Provides all client-side APIs needed for E2EE implementation\n- 🔒 **Secure FileDrop integration**: Enables secure file sharing with encryption\n- 🛡️ **Zero-knowledge architecture**: Server never has access to encryption keys\n- ⚙️ **Group restrictions**: Limit app usage to specific user groups if needed\n- 🔄 **Background job management**: Automatic rollback handling for failed operations\n\n### Setup\nThis application provides the server-side infrastructure for end-to-end encryption, but it requires client support to function.\nTo enable end-to-end encryption, users will need to install the corresponding client-side app on their devices (desktop, Android, iOS) or use the web client.\n\nUsing the web interface, after enabling it in the personal settings, allows you to encrypt files and folders directly in the browser,\nproviding a seamless experience without needing additional software. But also requires some kind of trust in the server as the code is delivered by the server and could be manipulated.\n\nOnce enable through clients or the web interface, you can create encrypted folders and upload or move files into them.\nThe clients and the web interface will handle the encryption and decryption processes automatically.\n\n⚠️ This comes with some limitations and caveats, as only normal file operations can be handled.\nMeaning that some apps in the web interface do not work with encrypted files.",
|
||||
"homepage": "https://github.com/nextcloud/end_to_end_encryption",
|
||||
"licenses": [
|
||||
"agpl"
|
||||
"AGPL-3.0-or-later"
|
||||
]
|
||||
},
|
||||
"files_automatedtagging": {
|
||||
@@ -140,9 +140,9 @@
|
||||
]
|
||||
},
|
||||
"gpoddersync": {
|
||||
"hash": "sha256-9BcXVauZWFlmlXtnwdSo5xISbhhssa7ao5ulKpziOnU=",
|
||||
"url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.16.0/gpoddersync.tar.gz",
|
||||
"version": "3.16.0",
|
||||
"hash": "sha256-V4iJr1p5uqxdrvE50bjyNTiHdsZATewaBXKQ8Ma0dHg=",
|
||||
"url": "https://github.com/thrillfall/nextcloud-gpodder/releases/download/3.17.0/gpoddersync.tar.gz",
|
||||
"version": "3.17.0",
|
||||
"description": "Expose GPodder API to sync podcast consumer apps like AntennaPod",
|
||||
"homepage": "https://github.com/thrillfall/nextcloud-gpodder",
|
||||
"licenses": [
|
||||
@@ -210,9 +210,9 @@
|
||||
]
|
||||
},
|
||||
"mail": {
|
||||
"hash": "sha256-K6sJ3XJOq9MoO0lGgqn3iBYuDqqhOMeHWD1DLVY5HaU=",
|
||||
"url": "https://github.com/nextcloud-releases/mail/releases/download/v5.10.1/mail-v5.10.1.tar.gz",
|
||||
"version": "5.10.1",
|
||||
"hash": "sha256-GkLTk3Q1mSUGhU6lsNHmHGkwW6u4XoDCOj405vi8xuY=",
|
||||
"url": "https://github.com/nextcloud-releases/mail/releases/download/v5.10.3/mail-v5.10.3.tar.gz",
|
||||
"version": "5.10.3",
|
||||
"description": "**💌 A mail app for Nextcloud**\n\n- **🚀 Integration with other Nextcloud apps!** Currently Contacts, Calendar & Files – more to come.\n- **📥 Multiple mail accounts!** Personal and company account? No problem, and a nice unified inbox. Connect any IMAP account.\n- **🔒 Send & receive encrypted mails!** Using the great [Mailvelope](https://mailvelope.com) browser extension.\n- **🙈 We’re not reinventing the wheel!** Based on the great [Horde](https://www.horde.org) libraries.\n- **📬 Want to host your own mail server?** We do not have to reimplement this as you could set up [Mail-in-a-Box](https://mailinabox.email)!\n\n## Ethical AI Rating\n\n### Priority Inbox\n\nPositive:\n* The software for training and inferencing of this model is open source.\n* The model is created and trained on-premises based on the user's own data.\n* The training data is accessible to the user, making it possible to check or correct for bias or optimise the performance and CO2 usage.\n\n### Thread Summaries (opt-in)\n\n**Rating:** 🟢/🟡/🟠/🔴\n\nThe rating depends on the installed text processing backend. See [the rating overview](https://docs.nextcloud.com/server/latest/admin_manual/ai/index.html) for details.\n\nLearn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud.com/blog/nextcloud-ethical-ai-rating/).",
|
||||
"homepage": "https://github.com/nextcloud/mail#readme",
|
||||
"licenses": [
|
||||
@@ -290,9 +290,9 @@
|
||||
]
|
||||
},
|
||||
"onlyoffice": {
|
||||
"hash": "sha256-ktKopFpHmtRulOQN3XO5BW5QyhURhOv+G77dSn6Nv08=",
|
||||
"url": "https://github.com/ONLYOFFICE/onlyoffice-nextcloud/releases/download/v10.1.0/onlyoffice.tar.gz",
|
||||
"version": "10.1.0",
|
||||
"hash": "sha256-QaohaMbw7bncBqreb5W8XngzqqwqALnsGgT494xfr/E=",
|
||||
"url": "https://github.com/ONLYOFFICE/onlyoffice-nextcloud/releases/download/v10.1.2/onlyoffice.tar.gz",
|
||||
"version": "10.1.2",
|
||||
"description": "The ONLYOFFICE app for Nextcloud brings powerful document editing and collaboration tools directly to your Nextcloud environment. With this integration, you can seamlessly create, edit, and co-author text documents, spreadsheets, presentations, and PDFs, as well as build and fill out PDF forms.\n\nCollaborate with your team in real time, make use of Track Changes, version history, comments, integrated chat, and more. Work together on files with federated cloud sharing. Flexible access permissions allow you to control who can view, edit, or comment, ensuring secure role-based collaboration tailored to your needs. Documents can also be protected with watermarks, password settings, and encryption for added security.\n\nThe app offers support for over 50 file formats, including DOCX, XLSX, PPTX, PDF, RTF, TXT, CSV, ODT, ODS, ODP, EPUB, FB2, HTML, HWP, HWPX, Pages, Numbers, Keynote, etc. Seamless desktop and mobile app integration means you'll have access to your Nextcloud files wherever you go.\n\nFurthermore, you can seamlessly connect any AI assistant, including local ones, directly to the editors to work faster and more efficient. This allows you to leverage various AI models for tasks like chatbot interactions, translations, OCR, and more.\n\nWhether you’re working with internal teams or external collaborators, the ONLYOFFICE app for Nextcloud enhances productivity, simplifies workflows, and ensures your files remain secure.",
|
||||
"homepage": "https://www.onlyoffice.com",
|
||||
"licenses": [
|
||||
@@ -410,9 +410,9 @@
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"hash": "sha256-I5QdNavgv74FSuXwFWNz/++LOY9Z8kNZhEKf2k118L8=",
|
||||
"url": "https://github.com/nextcloud/tasks/releases/download/v0.17.1/tasks.tar.gz",
|
||||
"version": "0.17.1",
|
||||
"hash": "sha256-nJFU65dthPRWd/SClKM/suZdYU3ic3QsIcXiPzUkQ6c=",
|
||||
"url": "https://github.com/nextcloud/tasks/releases/download/v0.18.0/tasks.tar.gz",
|
||||
"version": "0.18.0",
|
||||
"description": "Once enabled, a new Tasks menu will appear in your Nextcloud apps menu. From there you can add and delete tasks, edit their title, description, start and due dates and mark them as important. Tasks can be shared between users. Tasks can be synchronized using CalDav (each task list is linked to an Nextcloud calendar, to sync it to your local client: Thunderbird, Evolution, KDE Kontact, iCal … - just add the calendar as a remote calendar in your client). You can download your tasks as ICS files using the download button for each calendar.",
|
||||
"homepage": "https://github.com/nextcloud/tasks/",
|
||||
"licenses": [
|
||||
|
||||
Reference in New Issue
Block a user