Merge remote-tracking branch 'upstream/master' into spark/aarch64-settings-boot-dropins
# Conflicts: # .github/workflows/test.yml
This commit is contained in:
commit
19976635bc
145 files changed
+5560
-158
No files matched your search
@@ -0,0 +1,27 @@
|
||||
# Trust list for PR builds.
|
||||
#
|
||||
# A pull request only builds packages (and spins up builder droplets) when
|
||||
# its author is trusted: repository collaborators are trusted automatically
|
||||
# and do not need listing; external contributors listed here are trusted
|
||||
# too. Anyone else gets the plan only, until a maintainer either adds them
|
||||
# here or applies the "build-approved" label to that one PR. The label also
|
||||
# releases GitHub's approval hold for that PR's build and test workflows.
|
||||
# It remains effective while attached, without vouching for the author's
|
||||
# other PRs. An explicit denouncement cannot be overridden by the label.
|
||||
#
|
||||
# Syntax:
|
||||
# github:username
|
||||
# -github:username reason for denouncement
|
||||
#
|
||||
# Keep entries sorted alphabetically.
|
||||
github:bjarneo
|
||||
github:DanWahlin
|
||||
github:dhh
|
||||
github:f-trycua
|
||||
github:HANCORE-linux
|
||||
github:kwilczynski
|
||||
github:ryanrhughes
|
||||
github:scottjones
|
||||
github:spencerbull
|
||||
github:tcballard
|
||||
github:tobi
|
||||
@@ -0,0 +1,78 @@
|
||||
const BUILD = '.github/workflows/build-pr.yml';
|
||||
const TESTS = '.github/workflows/test.yml';
|
||||
|
||||
module.exports = async function approve({ github, context, core, vouchStatus,
|
||||
sleep = ms => new Promise(resolve => setTimeout(resolve, ms)), attempts = 36 }) {
|
||||
// Missing/failed vouch lookups must not become approval. Denouncements
|
||||
// remain absolute, just as they are in the package build gate.
|
||||
if (!['unknown', 'bot', 'collaborator', 'vouched'].includes(vouchStatus)) {
|
||||
throw new Error(`Cannot approve workflows: vouch status is ${vouchStatus || 'missing'}.`);
|
||||
}
|
||||
|
||||
const expected = context.payload.pull_request;
|
||||
const eventTime = Date.parse(expected.updated_at);
|
||||
if (!Number.isFinite(eventTime)) throw new Error('Missing PR event timestamp.');
|
||||
const approved = new Set();
|
||||
let precedingBuild;
|
||||
|
||||
const stillApproved = async () => {
|
||||
const { data: pr } = await github.rest.pulls.get({
|
||||
...context.repo, pull_number: expected.number,
|
||||
});
|
||||
return pr.state === 'open' && pr.head.sha === expected.head.sha &&
|
||||
pr.labels.some(label => label.name === 'build-approved');
|
||||
};
|
||||
|
||||
// The label and PR-run events arrive independently. Wait for the build
|
||||
// belonging to this event, rather than returning after approving an older
|
||||
// run and leaving the new label-triggered run stuck behind GitHub's gate.
|
||||
for (let attempt = 0; attempt < attempts; attempt++) {
|
||||
if (attempt) await sleep(5000);
|
||||
if (!await stillApproved()) {
|
||||
core.info('PR closed, head changed, or build-approved removed; stopping.');
|
||||
return;
|
||||
}
|
||||
|
||||
const all = await github.paginate(github.rest.actions.listWorkflowRunsForRepo, {
|
||||
...context.repo, event: 'pull_request', head_sha: expected.head.sha, per_page: 100,
|
||||
});
|
||||
const runs = all.filter(run =>
|
||||
run.event === 'pull_request' && run.head_sha === expected.head.sha &&
|
||||
run.head_repository?.id === expected.head.repo.id && run.head_branch === expected.head.ref &&
|
||||
[BUILD, TESTS].includes(run.path) &&
|
||||
// Fork runs awaiting approval often have no pull_requests entries.
|
||||
(!run.pull_requests?.length || run.pull_requests.some(pr => pr.number === expected.number))
|
||||
).sort((a, b) => a.id - b.id);
|
||||
|
||||
const newestBuild = runs.findLast(run => run.path === BUILD);
|
||||
if (!newestBuild || !(Date.parse(newestBuild.created_at) >= eventTime) ||
|
||||
!runs.some(run => run.path === TESTS &&
|
||||
(context.payload.action === 'labeled' || Date.parse(run.created_at) >= eventTime))) continue;
|
||||
|
||||
if (precedingBuild) {
|
||||
const { data: run } = await github.rest.actions.getWorkflowRun({
|
||||
...context.repo, run_id: precedingBuild,
|
||||
});
|
||||
// Approve older builds first, and let them acquire concurrency before
|
||||
// releasing a newer build. Otherwise an older queued run could start
|
||||
// last and cancel the label-triggered build that carries approval.
|
||||
if (!['in_progress', 'completed'].includes(run.status) || run.conclusion === 'action_required') continue;
|
||||
precedingBuild = undefined;
|
||||
}
|
||||
|
||||
const pending = runs.filter(run => run.conclusion === 'action_required' && !approved.has(run.id) &&
|
||||
// If the newest build already runs (e.g. a maintainer approved it),
|
||||
// don't resurrect an obsolete hold that could cancel that newer run.
|
||||
(run.path !== BUILD || run.id === newestBuild.id || newestBuild.conclusion === 'action_required'));
|
||||
if (!pending.length) return;
|
||||
const run = pending[0];
|
||||
// Recheck after the API reads, immediately before exercising write access.
|
||||
if (!await stillApproved()) return;
|
||||
await github.rest.actions.approveWorkflowRun({ ...context.repo, run_id: run.id });
|
||||
approved.add(run.id);
|
||||
core.info(`Approved ${run.path} run ${run.id} for PR #${expected.number}.`);
|
||||
if (run.path === BUILD) precedingBuild = run.id;
|
||||
if (pending.length === 1) return;
|
||||
}
|
||||
throw new Error('Timed out waiting for PR workflows. Remove and reapply build-approved to retry.');
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
name: Approve PR workflows
|
||||
|
||||
# A pull_request workflow cannot approve itself: GitHub can hold it before
|
||||
# any job starts. This workflow only runs trusted default-branch code and
|
||||
# releases the ordinary, unprivileged PR workflows after build approval.
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
actions: write
|
||||
|
||||
concurrency:
|
||||
group: approve-pr-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
approve:
|
||||
# Match build-pr.yml's events, including other labels applied while this
|
||||
# PR still carries build-approved: each labeled event creates a build.
|
||||
if: contains(github.event.pull_request.labels.*.name, 'build-approved')
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
# Never check out the PR head or its merge ref with this write token.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.repository.default_branch }}
|
||||
persist-credentials: false
|
||||
- id: vouch
|
||||
uses: mitchellh/vouch/action/check-user@f23dbb5e745334f97414ec70463ce7301071a661 # v1
|
||||
with:
|
||||
user: ${{ github.event.pull_request.user.login }}
|
||||
allow-fail: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Approve this PR's pending build and test runs
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
VOUCH_STATUS: ${{ steps.vouch.outputs.status }}
|
||||
with:
|
||||
script: |
|
||||
const approve = require('./.github/scripts/approve-pr-workflows.cjs');
|
||||
await approve({ github, context, core, vouchStatus: process.env.VOUCH_STATUS });
|
||||
@@ -0,0 +1,254 @@
|
||||
name: Build changed packages
|
||||
|
||||
# Build every package directory a PR touches, one job per package per arch, on
|
||||
# the self-hosted droplet pool. Artifacts are unsigned; publish.yml signs and
|
||||
# publishes them on merge.
|
||||
#
|
||||
# Tooling runs from the base branch; a PR supplies only pkgbuilds/. The
|
||||
# vouch gate limits who may spend compute; this limits what their PR can run.
|
||||
|
||||
# No paths filter: approved PRs must report the required `result` even when
|
||||
# no package directory changed. Those PRs get an empty matrix and a passing
|
||||
# result in seconds; unapproved PRs wait for maintainer approval.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
packages:
|
||||
description: "Space-separated package directories to build"
|
||||
required: true
|
||||
|
||||
concurrency:
|
||||
group: build-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Builds cost real machines, so they run only for trusted authors:
|
||||
# collaborators, anyone in .github/VOUCHED.td (read from the default
|
||||
# branch, so a PR cannot vouch for itself), or a PR a maintainer has
|
||||
# labelled "build-approved". Everyone else gets this job's plan output
|
||||
# while the required `result` stays pending until a maintainer approves.
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.list.outputs.matrix }}
|
||||
count: ${{ steps.gate.outputs.count }}
|
||||
trusted: ${{ steps.gate.outputs.trusted }}
|
||||
vouch_status: ${{ steps.vouch.outputs.status }}
|
||||
empty: ${{ steps.list.outputs.empty }}
|
||||
steps:
|
||||
# Same rule as the build job: bin/build-matrix comes from the base
|
||||
# branch tip, the package directories from the PR head.
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.ref || github.sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
git fetch --no-tags --depth=1 origin "${{ github.event.pull_request.head.sha }}"
|
||||
git checkout "${{ github.event.pull_request.head.sha }}" -- pkgbuilds/
|
||||
# Bootstrap: the PR that introduces this tooling has a base without
|
||||
# it. Take the plan helper from the PR head in that one case; it
|
||||
# runs on a hosted runner and only prints a plan.
|
||||
if [[ ! -x bin/build-matrix ]]; then
|
||||
git checkout "${{ github.event.pull_request.head.sha }}" -- bin/build-matrix helpers/
|
||||
echo "::notice::base branch has no bin/build-matrix; using the PR's copy for planning"
|
||||
fi
|
||||
- id: vouch
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: mitchellh/vouch/action/check-user@f23dbb5e745334f97414ec70463ce7301071a661 # v1
|
||||
with:
|
||||
user: ${{ github.event.pull_request.user.login }}
|
||||
allow-fail: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- id: approval
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { data: pr } = await github.rest.pulls.get({
|
||||
...context.repo, pull_number: context.payload.pull_request.number,
|
||||
});
|
||||
// Approving or rerunning a held run keeps its original event,
|
||||
// which may predate the label. Read the current approval instead.
|
||||
core.setOutput('approved', pr.state === 'open' &&
|
||||
pr.head.sha === context.payload.pull_request.head.sha &&
|
||||
pr.labels.some(label => label.name === 'build-approved'));
|
||||
# One matrix entry per package per architecture. Every package builds
|
||||
# once, against edge; the channels it ships to on merge are carried
|
||||
# along for information. A filename means one set of bytes.
|
||||
- id: list
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
if [[ -n "${{ github.event.inputs.packages }}" ]]; then
|
||||
names="${{ github.event.inputs.packages }}"
|
||||
else
|
||||
names=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" -- pkgbuilds \
|
||||
| awk -F/ '$1=="pkgbuilds" && NF>2 {print $2}' | sort -u)
|
||||
fi
|
||||
matrix=$(printf '%s\n' $names | bin/build-matrix)
|
||||
# A package directory whose exact tree already has a build artifact
|
||||
# (label <pkg>-<arch>-<tree hash>, uploaded only after a successful
|
||||
# build) is not built again. Pushing a fix for one package to a PR
|
||||
# that touches fifty rebuilds one, not fifty; publish.yml finds the
|
||||
# same artifacts on merge. workflow_dispatch is an explicit request
|
||||
# and always builds.
|
||||
if [[ "${{ github.event_name }}" == pull_request ]]; then
|
||||
head="${{ github.event.pull_request.head.sha }}"
|
||||
kept=(); reused=()
|
||||
while read -r entry; do
|
||||
package=$(jq -r .package <<<"$entry"); arch=$(jq -r .arch <<<"$entry")
|
||||
label="$package-$arch-$(git rev-parse "$head:pkgbuilds/$package")"
|
||||
found=$(curl -fsS -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/actions/artifacts?name=$label&per_page=5" \
|
||||
| jq -r '[.artifacts[] | select(.expired|not)] | length' || echo 0)
|
||||
if (( found > 0 )); then reused+=("$label"); else kept+=("$entry"); fi
|
||||
done < <(jq -c '.include[]' <<<"$matrix")
|
||||
matrix=$(printf '%s\n' "${kept[@]}" | jq -sc '{include: .}')
|
||||
if (( ${#reused[@]} )); then
|
||||
printf '==> already built, reusing the artifact: %s\n' "${reused[@]}"
|
||||
{ echo "Reused existing build artifacts (${#reused[@]}):"; printf -- '- %s\n' "${reused[@]}"; } >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
fi
|
||||
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
|
||||
echo "planned=$(jq '.include | length' <<<"$matrix")" >> "$GITHUB_OUTPUT"
|
||||
jq -r '.include[] | "\(.package) \(.arch) -> \(.channels)"' <<<"$matrix"
|
||||
# A PR whose diff against its base is empty changes nothing: its
|
||||
# content already landed some other way (a sync PR beat it, or a
|
||||
# merge from master swallowed it). Merging it would record a change
|
||||
# that isn't one. Flag it so `result` fails rather than passes.
|
||||
if [[ "${{ github.event_name }}" == pull_request ]]; then
|
||||
total=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | wc -l)
|
||||
echo "empty=$([[ $total -eq 0 ]] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
||||
echo "files changed vs base: $total"
|
||||
else
|
||||
echo "empty=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- id: gate
|
||||
env:
|
||||
STATUS: ${{ github.event_name == 'workflow_dispatch' && 'dispatch' || steps.vouch.outputs.status }}
|
||||
AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
APPROVED: ${{ steps.approval.outputs.approved || 'false' }}
|
||||
PLANNED: ${{ steps.list.outputs.planned }}
|
||||
run: |
|
||||
case "$STATUS" in
|
||||
bot|collaborator|vouched|dispatch) trusted=true ;;
|
||||
# A denouncement is absolute: the label cannot override it.
|
||||
denounced) trusted=false ;;
|
||||
unknown) trusted=$APPROVED ;;
|
||||
*) trusted=false ;;
|
||||
esac
|
||||
echo "trusted=$trusted" >> "$GITHUB_OUTPUT"
|
||||
if [[ $trusted == true ]]; then
|
||||
echo "count=$PLANNED" >> "$GITHUB_OUTPUT"
|
||||
echo "Author $AUTHOR is trusted ($STATUS); building $PLANNED package(s)."
|
||||
else
|
||||
echo "count=0" >> "$GITHUB_OUTPUT"
|
||||
echo "::warning::Author $AUTHOR is not trusted ($STATUS). $PLANNED package build(s) planned but not run."
|
||||
if [[ $STATUS == denounced ]]; then
|
||||
echo "::warning::The author is denounced in .github/VOUCHED.td; the build-approved label does not apply."
|
||||
else
|
||||
echo "::warning::A maintainer can add the author to .github/VOUCHED.td, or apply the 'build-approved' label to build this PR."
|
||||
fi
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.count != '0'
|
||||
runs-on: [self-hosted, omarchy-builder]
|
||||
timeout-minutes: 180
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.changes.outputs.matrix) }}
|
||||
steps:
|
||||
# Tooling from base: everything that executes on this droplet's host
|
||||
# (bin/, helpers/, build/) comes from the base branch. Only the PR's
|
||||
# package directories are overlaid. A PR can therefore change what
|
||||
# gets built, never how the runner builds it. A PR that changes both
|
||||
# tooling and a package builds the package with the OLD tooling; land
|
||||
# the tooling first. workflow_dispatch has no PR and runs as checked out.
|
||||
# The base branch tip, not the event's base.sha: that sha is a snapshot
|
||||
# taken at the PR's last push, so a tooling fix on master would never
|
||||
# reach an open PR until someone pushed to it (seen on the daily sync
|
||||
# PR after the artifact packing fix landed).
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.ref || github.sha }}
|
||||
persist-credentials: false
|
||||
- name: Overlay the PR's package directories onto base tooling
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git fetch --no-tags --depth=1 origin "${{ github.event.pull_request.head.sha }}"
|
||||
git checkout "${{ github.event.pull_request.head.sha }}" -- pkgbuilds/
|
||||
echo "tooling: $(git rev-parse --short HEAD) (base) packages: ${{ github.event.pull_request.head.sha }} (PR head)"
|
||||
git status --short | head
|
||||
- name: Build ${{ matrix.package }} (${{ matrix.arch }}, ships to ${{ matrix.channels }})
|
||||
id: build
|
||||
env:
|
||||
CONTAINER_ENGINE: docker
|
||||
run: bin/build --mirror edge --arch ${{ matrix.arch }} --package ${{ matrix.package }}
|
||||
# The artifact label carries the package directory's git tree hash so
|
||||
# the publish step can find the build for exactly the tree that merged.
|
||||
# The package file inside keeps makepkg's standard name untouched.
|
||||
# The artifact label uses the PR head's tree for this package: that is
|
||||
# the tree that merges, and what publish looks up.
|
||||
- name: Tree hash
|
||||
id: tree
|
||||
run: echo "hash=$(git rev-parse "${{ github.event.pull_request.head.sha || github.sha }}:pkgbuilds/${{ matrix.package }}")" >> "$GITHUB_OUTPUT"
|
||||
# The upload action rejects a path containing ':', which is how makepkg
|
||||
# names a package with an epoch. The files ride inside packages.tar
|
||||
# (helpers/artifact-helpers.sh); publish.yml unpacks it. Only a
|
||||
# successful build uploads: the artifact's existence is what lets the
|
||||
# planner above and publish.yml skip rebuilding this exact tree.
|
||||
- name: Pack artifact
|
||||
id: pack
|
||||
run: |
|
||||
source helpers/artifact-helpers.sh
|
||||
pack_packages build-output/edge/${{ matrix.arch }} packages.tar
|
||||
tar -tvf packages.tar
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.package }}-${{ matrix.arch }}-${{ steps.tree.outputs.hash }}
|
||||
path: packages.tar
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
# `result` is required by branch protection. An unvouched author awaiting
|
||||
# approval gets a differently named informational check, leaving `result`
|
||||
# unreported (pending). Skipping or passing a job named `result` would count
|
||||
# as satisfying the requirement even though no build was authorized.
|
||||
# Actual planning/build failures and denouncements still report `result`.
|
||||
result:
|
||||
name: ${{ needs.changes.result == 'success' && needs.changes.outputs.trusted == 'false' && needs.changes.outputs.vouch_status == 'unknown' && needs.changes.outputs.empty == 'false' && 'Awaiting build approval' || 'result' }}
|
||||
needs: [changes, build]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
echo "trusted=${{ needs.changes.outputs.trusted }} build=${{ needs.build.result }}"
|
||||
if [[ "${{ needs.changes.result }}" != "success" ]]; then
|
||||
echo "::error::Build planning or the trust check failed. See the changes job."
|
||||
exit 1
|
||||
fi
|
||||
# Nothing to merge: the PR's diff against its base is empty. Its
|
||||
# change already landed elsewhere. Close it rather than merge it.
|
||||
if [[ "${{ needs.changes.outputs.empty }}" == "true" ]]; then
|
||||
echo "::error::This PR changes no files relative to its base. Its content is already on the target branch; close it instead of merging."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${{ needs.changes.outputs.trusted }}" == "false" && "${{ needs.changes.outputs.vouch_status }}" == "unknown" && "${{ needs.changes.outputs.empty }}" == "false" ]]; then
|
||||
echo "::notice::Awaiting maintainer build approval. Apply 'build-approved' to this PR or vouch for the author in .github/VOUCHED.td."
|
||||
echo "Package builds are waiting for maintainer approval. Apply **build-approved** to this PR to start them. The required **result** check remains pending." >> "$GITHUB_STEP_SUMMARY"
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${{ needs.changes.outputs.trusted }}" != "true" ]]; then
|
||||
echo "::error::Builds are blocked: the author is denounced or the trust result is invalid. The build-approved label cannot override this."
|
||||
exit 1
|
||||
fi
|
||||
[[ "${{ needs.build.result }}" == "success" || "${{ needs.build.result }}" == "skipped" ]]
|
||||
@@ -0,0 +1,118 @@
|
||||
name: Refresh builder images
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '23 4 * * *'
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- build/**
|
||||
- bin/builder-image
|
||||
- helpers/paths.sh
|
||||
- helpers/docker-helpers.sh
|
||||
- tests/build-isolation.sh
|
||||
- .github/workflows/builder-images.yml
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- build/**
|
||||
- bin/builder-image
|
||||
- helpers/paths.sh
|
||||
- helpers/docker-helpers.sh
|
||||
- tests/build-isolation.sh
|
||||
- .github/workflows/builder-images.yml
|
||||
|
||||
# Complete each refresh before another can replace its tested image tags.
|
||||
concurrency:
|
||||
group: builder-images-${{ github.event.pull_request.number || 'master' }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# Exercise proposed image changes on native runners with a read-only token.
|
||||
# Publishing is a separate master-only job with its own write permission.
|
||||
validate:
|
||||
if: github.event_name == 'pull_request'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
runner: ubuntu-24.04
|
||||
- arch: aarch64
|
||||
runner: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CONTAINER_ENGINE: docker
|
||||
CANDIDATE_IMAGE: omarchy-builder-candidate:${{ matrix.arch }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Build a fresh environment
|
||||
run: bin/builder-image build --arch "${{ matrix.arch }}" --mirror edge --tag "$CANDIDATE_IMAGE" --fresh
|
||||
- name: Test isolated package builds
|
||||
env:
|
||||
TEST_BUILDER_IMAGE: ${{ env.CANDIDATE_IMAGE }}
|
||||
run: tests/build-isolation.sh
|
||||
|
||||
refresh:
|
||||
if: github.repository == 'omacom/omarchy-pkgs' && github.ref == 'refs/heads/master'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
runner: ubuntu-24.04
|
||||
- arch: aarch64
|
||||
runner: ubuntu-24.04-arm
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
env:
|
||||
CONTAINER_ENGINE: docker
|
||||
REGISTRY_IMAGE: ghcr.io/omacom/omarchy-pkg-builder
|
||||
CANDIDATE_IMAGE: omarchy-builder-candidate:${{ matrix.arch }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Build a fresh environment
|
||||
run: bin/builder-image build --arch "${{ matrix.arch }}" --mirror edge --tag "$CANDIDATE_IMAGE" --fresh
|
||||
- name: Test isolated package builds
|
||||
env:
|
||||
TEST_BUILDER_IMAGE: ${{ env.CANDIDATE_IMAGE }}
|
||||
run: tests/build-isolation.sh
|
||||
- name: Publish tested image
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_ACTOR: ${{ github.actor }}
|
||||
DOCKER_CONFIG: ${{ runner.temp }}/builder-registry-auth
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p "$DOCKER_CONFIG"
|
||||
trap 'rm -rf "$DOCKER_CONFIG"' EXIT
|
||||
printf '%s' "$GH_TOKEN" | docker login ghcr.io --username "$GH_ACTOR" --password-stdin
|
||||
key=$(bin/builder-image key --arch "${{ matrix.arch }}" --mirror edge)
|
||||
version="$REGISTRY_IMAGE:$key-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
|
||||
docker tag "$CANDIDATE_IMAGE" "$version"
|
||||
docker push "$version"
|
||||
# GHCR creates new packages private. Do not advertise an image to
|
||||
# fork PRs until it is public. This is a one-time package setting.
|
||||
anonymous_config=$(mktemp -d "$RUNNER_TEMP/builder-anonymous.XXXXXX")
|
||||
if ! DOCKER_CONFIG="$anonymous_config" docker manifest inspect "$version" >/dev/null; then
|
||||
rm -rf "$anonymous_config"
|
||||
echo "::error::Make the omacom/omarchy-pkg-builder GHCR package public, then rerun this job. The previous matching image remains selected."
|
||||
exit 1
|
||||
fi
|
||||
rm -rf "$anonymous_config"
|
||||
docker tag "$CANDIDATE_IMAGE" "$REGISTRY_IMAGE:$key"
|
||||
docker push "$REGISTRY_IMAGE:$key"
|
||||
digest=$(docker image inspect "$version" --format '{{index .RepoDigests 0}}')
|
||||
printf '### Builder image (%s)\n\nInput key: `%s`\n\nImage: `%s`\n' \
|
||||
"${{ matrix.arch }}" "$key" "$digest" >> "$GITHUB_STEP_SUMMARY"
|
||||
@@ -0,0 +1,326 @@
|
||||
name: Publish merged packages
|
||||
|
||||
# On every push to master: for each package directory the push touched and
|
||||
# each architecture it supports, find the PR build artifact for exactly that
|
||||
# tree (label = <pkg>-<arch>-<treehash>), or build it now when there is
|
||||
# none, then publish that one artifact into every channel the package ships
|
||||
# to. One build, one file, several databases: a filename means one set of
|
||||
# bytes everywhere, and channels are views over a shared pool.
|
||||
#
|
||||
# Secrets live in the "publish" environment, restricted to master:
|
||||
# GPG_PRIVATE_KEY, GPG_PASSPHRASE the channel signing key
|
||||
# R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_ENDPOINT
|
||||
# OMARCHY_PUBLISH_PREFIX (environment variable, not secret) points a proof
|
||||
# run at a scratch prefix inside the live bucket; empty means the real
|
||||
# channel paths.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths: ["pkgbuilds/**"]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
packages:
|
||||
description: "Space-separated package directories to publish from master"
|
||||
required: true
|
||||
|
||||
# Merges serialize. Two publishes into one channel at once would race on
|
||||
# the database; queued is fine, cancelled is not.
|
||||
concurrency:
|
||||
group: publish
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.list.outputs.matrix }}
|
||||
count: ${{ steps.list.outputs.count }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- id: list
|
||||
run: |
|
||||
if [[ -n "${{ github.event.inputs.packages }}" ]]; then
|
||||
names="${{ github.event.inputs.packages }}"
|
||||
else
|
||||
names=$(git diff --name-only "${{ github.event.before }}..${{ github.sha }}" -- pkgbuilds \
|
||||
| awk -F/ '$1=="pkgbuilds" && NF>2 {print $2}' | sort -u)
|
||||
fi
|
||||
matrix=$(printf '%s\n' $names | bin/build-matrix)
|
||||
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
|
||||
echo "count=$(jq '.include | length' <<<"$matrix")" >> "$GITHUB_OUTPUT"
|
||||
jq -r '.include[] | "\(.package) \(.arch) -> \(.channels)"' <<<"$matrix"
|
||||
|
||||
# One job for the whole merge. It collects every PR artifact for the
|
||||
# merged tree (building only what has none), then walks each channel and
|
||||
# architecture slot exactly once: pull that database, add every package
|
||||
# that belongs in it, upload. Six slots, six round trips, however many
|
||||
# packages the merge carried. One process is the only writer, so there
|
||||
# is no race between packages; the run-level concurrency group above
|
||||
# keeps one merge from overlapping the next.
|
||||
publish:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.count != '0'
|
||||
runs-on: [self-hosted, omarchy-builder]
|
||||
environment: publish
|
||||
timeout-minutes: 240
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Every matrix entry, as a file the shell steps can loop over:
|
||||
# package arch channels publish_arches
|
||||
- name: Plan
|
||||
run: |
|
||||
jq -r '.include[] | "\(.package) \(.arch) \(.channels|gsub(" ";",")) \(.publish_arches|gsub(" ";","))"' \
|
||||
<<'EOF_MATRIX' > plan.txt
|
||||
${{ needs.changes.outputs.matrix }}
|
||||
EOF_MATRIX
|
||||
cat plan.txt
|
||||
|
||||
# Fetch each package's PR artifact into build-output/edge/<arch>/, or
|
||||
# build it when no artifact exists for exactly this tree. An artifact
|
||||
# carries its package files inside packages.tar (see build-pr.yml and
|
||||
# helpers/artifact-helpers.sh: the upload action rejects the colon in
|
||||
# an epoch filename).
|
||||
- name: Collect artifacts
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
CONTAINER_ENGINE: docker
|
||||
run: |
|
||||
set -uo pipefail
|
||||
source helpers/artifact-helpers.sh
|
||||
# sources.jsonl: where each package's files came from, or that the
|
||||
# build failed. A failed build ends the run before any publish, and
|
||||
# the record says so instead of the report job finding nothing.
|
||||
: > sources.jsonl
|
||||
failed=0
|
||||
while read -r package arch channels publish_arches; do
|
||||
hash=$(git rev-parse "HEAD:pkgbuilds/$package")
|
||||
label="$package-$arch-$hash"
|
||||
found=$(curl -fsS -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/${{ github.repository }}/actions/artifacts?name=$label&per_page=5" \
|
||||
| jq -r '[.artifacts[] | select(.expired|not)] | sort_by(.created_at) | last | .archive_download_url // empty')
|
||||
mkdir -p "build-output/edge/$arch"
|
||||
if [[ -n "$found" ]]; then
|
||||
echo "==> $label: PR artifact"
|
||||
rm -rf /tmp/artifact; mkdir -p /tmp/artifact
|
||||
if curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -o /tmp/artifact.zip "$found" \
|
||||
&& unzip -oq /tmp/artifact.zip -d /tmp/artifact \
|
||||
&& unpack_packages /tmp/artifact "build-output/edge/$arch"; then
|
||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"pr-artifact"}' >> sources.jsonl
|
||||
else
|
||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"artifact-download-failed"}' >> sources.jsonl; failed=1; break
|
||||
fi
|
||||
else
|
||||
# bin/build plans against the public channel first. If the
|
||||
# channel already holds master's version there is nothing to
|
||||
# build and nothing to publish: a re-run for a package that
|
||||
# turned out to be fine. Record it and move on.
|
||||
plan=$(CONTAINER_ENGINE=docker bin/build --dry-run --mirror edge --arch "$arch" --package "$package" 2>&1 | grep -E '^==> Plan complete' || true)
|
||||
# "Packages that would build:" followed by nothing means none.
|
||||
if [[ -n "$plan" && -z "$(sed -E 's/.*would build: *//' <<<"$plan" | tr -d '[:space:]')" ]]; then
|
||||
echo "==> $label: already published at master's version, nothing to do"
|
||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"already-published"}' >> sources.jsonl
|
||||
continue
|
||||
fi
|
||||
echo "==> $label: no artifact for this tree, building"
|
||||
if OMARCHY_KEEP_BUILD_WORKSPACE=1 bin/build --mirror edge --arch "$arch" --package "$package"; then
|
||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"built"}' >> sources.jsonl
|
||||
else
|
||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"build-failed"}' >> sources.jsonl; failed=1; break
|
||||
fi
|
||||
fi
|
||||
done < plan.txt
|
||||
ls -1 build-output/edge/*/*.pkg.tar.zst 2>/dev/null || true
|
||||
if (( failed )); then
|
||||
# Write the record now; the publish step will not run.
|
||||
jq -n --arg sha "${{ github.sha }}" --arg run "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||
--arg prefix "${OMARCHY_PUBLISH_PREFIX:-}" --arg event "${{ github.event_name }}" \
|
||||
--slurpfile sources sources.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \
|
||||
'{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], sources:$sources, slots:[]}' \
|
||||
> publish-record.json
|
||||
cat publish-record.json
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Publish
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
RCLONE_CONFIG_R2_TYPE: s3
|
||||
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
|
||||
# The token is scoped to the bucket; it may not CreateBucket, and
|
||||
# rclone's existence check is a CreateBucket in disguise.
|
||||
RCLONE_CONFIG_R2_NO_CHECK_BUCKET: "true"
|
||||
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
OMARCHY_PUBLISH_PREFIX: ${{ vars.OMARCHY_PUBLISH_PREFIX }}
|
||||
# repo-add, gpg and bsdtar are Arch tools; run the publish inside the
|
||||
# builder image (host-native, edge) with the workspace mounted.
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if ! compgen -G "build-output/edge/*/*.pkg.tar.zst" >/dev/null; then
|
||||
echo "Nothing to publish: every requested package is already published at master's version."
|
||||
jq -n --arg sha "${{ github.sha }}" --arg run "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||
--arg prefix "${OMARCHY_PUBLISH_PREFIX:-}" --arg event "${{ github.event_name }}" \
|
||||
--slurpfile sources sources.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \
|
||||
'{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], sources:$sources, slots:[]}' \
|
||||
> publish-record.json
|
||||
cat publish-record.json
|
||||
exit 0
|
||||
fi
|
||||
docker image inspect omarchy-pkg-builder:latest-x86_64-edge >/dev/null 2>&1 \
|
||||
|| docker buildx build --load -t omarchy-pkg-builder:latest-x86_64-edge --build-arg MIRROR=edge build
|
||||
|
||||
# Group the merge's files by the (channel, architecture) slot each
|
||||
# belongs to. A package's files live under build-output/edge/<built
|
||||
# arch>/ and are named <pkgname>-<ver>-<arch|any>.pkg.tar.zst; a
|
||||
# split package's outputs share the pkgbase's directory, so match
|
||||
# on the artifact list rather than the name.
|
||||
# pkgbase is read inside the builder image: the Ubuntu host has no
|
||||
# bsdtar. One container call maps every file to its pkgbase.
|
||||
docker run --rm -v "$PWD:/w:ro" -w /w omarchy-pkg-builder:latest-x86_64-edge bash -c '
|
||||
for f in build-output/edge/*/*.pkg.tar.zst; do
|
||||
printf "%s %s\n" "$f" "$(bsdtar -xOf "$f" .PKGINFO | awk -F" = " "\$1==\"pkgbase\"{print \$2}")"
|
||||
done' > pkgbase.txt
|
||||
declare -A slot_files=()
|
||||
while read -r package arch channels publish_arches; do
|
||||
for f in build-output/edge/"$arch"/*.pkg.tar.zst; do
|
||||
# Only files this package produced (its PKGINFO pkgbase).
|
||||
[[ $(awk -v f="$f" '$1==f{print $2}' pkgbase.txt) == "$package" ]] || continue
|
||||
for mirror in ${channels//,/ }; do
|
||||
for parch in ${publish_arches//,/ }; do
|
||||
slot_files["$mirror/$parch"]+="$f "
|
||||
done
|
||||
done
|
||||
done
|
||||
done < plan.txt
|
||||
|
||||
# Deterministic slot order: edge before rc before stable, x86_64
|
||||
# before aarch64, so a failure leaves the earlier rings consistent.
|
||||
# Every slot's outcome goes into publish-record.json for the report
|
||||
# job: what was published, where, from which artifact, and whether
|
||||
# the slot succeeded. A failing slot stops the loop (set -e) but the
|
||||
# record still shows everything before it landed.
|
||||
: > slots.jsonl
|
||||
record_slot() { jq -nc --arg m "$1" --arg a "$2" --arg st "$3" --arg files "$4" \
|
||||
'{mirror:$m, arch:$a, status:$st, packages:[$files | split(" ") | .[] | select(length>0) | sub(".*/";"") | sub("\\.pkg\\.tar\\.zst$";"")]}' >> slots.jsonl; }
|
||||
status=0
|
||||
for mirror in edge rc stable; do
|
||||
for parch in x86_64 aarch64; do
|
||||
files=${slot_files["$mirror/$parch"]:-}
|
||||
[[ -n "$files" ]] || continue
|
||||
echo "==> $mirror/$parch: $files"
|
||||
if docker run --rm \
|
||||
-e GPG_PRIVATE_KEY -e GPG_PASSPHRASE -e OMARCHY_PUBLISH_PREFIX \
|
||||
-e RCLONE_CONFIG_R2_TYPE -e RCLONE_CONFIG_R2_PROVIDER -e RCLONE_CONFIG_R2_ENDPOINT -e RCLONE_CONFIG_R2_NO_CHECK_BUCKET \
|
||||
-e RCLONE_CONFIG_R2_ACCESS_KEY_ID -e RCLONE_CONFIG_R2_SECRET_ACCESS_KEY \
|
||||
-v "$PWD:/w:ro" -w /w \
|
||||
omarchy-pkg-builder:latest-x86_64-edge \
|
||||
bin/publish-artifact --remote R2:omarchy-pkgs --mirror "$mirror" --arch "$parch" $files; then
|
||||
record_slot "$mirror" "$parch" published "$files"
|
||||
else
|
||||
record_slot "$mirror" "$parch" failed "$files"
|
||||
status=1
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
jq -n --arg sha "${{ github.sha }}" --arg run "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||
--arg prefix "${OMARCHY_PUBLISH_PREFIX:-}" --arg event "${{ github.event_name }}" \
|
||||
--slurpfile slots slots.jsonl --slurpfile sources sources.jsonl --slurpfile plan <(jq -c '.include[]' <<<'${{ needs.changes.outputs.matrix }}' | jq -sc .) \
|
||||
'{time: (now|todate), commit:$sha, run:$run, event:$event, target: (if $prefix=="" then "live" else $prefix end), plan:$plan[0], sources:$sources, slots:$slots}' \
|
||||
> publish-record.json
|
||||
cat publish-record.json
|
||||
exit $status
|
||||
|
||||
- name: Keep the publish record
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: publish-record-${{ github.run_id }}
|
||||
path: publish-record.json
|
||||
retention-days: 90
|
||||
|
||||
# Tell people what happened. A comment on the merged PR (found by the
|
||||
# merge commit, so squash and rebase merges work too) and a line appended
|
||||
# to a running JSON log in the bucket, next to the packages it describes,
|
||||
# so the history is public and can be rendered later.
|
||||
report:
|
||||
needs: [changes, publish]
|
||||
if: always() && needs.publish.result != 'skipped'
|
||||
runs-on: ubuntu-latest
|
||||
environment: publish
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: publish-record-${{ github.run_id }}
|
||||
- name: Render
|
||||
id: render
|
||||
run: |
|
||||
jq -r --arg outcome "${{ needs.publish.result }}" '
|
||||
def pkgs: [.packages[] | select(test("-debug-")|not)] | join(", ");
|
||||
def src: if .source=="pr-artifact" then "PR artifact" elif .source=="built" then "built here" elif .source=="already-published" then "already published, skipped" else "**" + .source + "**" end;
|
||||
"### Publish " + (if $outcome=="success" then "succeeded" else "FAILED" end) +
|
||||
" → **" + .target + "**" + (if .target!="live" then " (proof prefix, not live)" else "" end),
|
||||
"",
|
||||
"Packages: " + ([.sources[] | .package + " (" + .arch + ", " + src + ")"] | join("; ")),
|
||||
"",
|
||||
(if (.slots|length) > 0 then (.slots[] | "- `" + .mirror + "/" + .arch + "`: " + (if .status=="published" then "" else "**" + .status + "** " end) + pkgs)
|
||||
elif ([.sources[] | select(.source=="already-published")] | length) == (.sources|length) then "_Nothing to publish: already at master'"'"'s version everywhere._"
|
||||
else "_Nothing was published._" end),
|
||||
"",
|
||||
(if ([.sources[] | select(.source|test("failed"))] | length) > 0 then "_A build failed, so no channel was touched._\n"
|
||||
elif (.plan|length) > (.slots|length) then "_Some planned slots did not run because an earlier slot failed._\n" else "" end),
|
||||
"Commit " + .commit[0:7] + " · [run](" + .run + ")"
|
||||
' publish-record.json > comment.md
|
||||
cat comment.md
|
||||
- name: Append to the publish log in the bucket
|
||||
env:
|
||||
RCLONE_CONFIG_R2_TYPE: s3
|
||||
RCLONE_CONFIG_R2_PROVIDER: Cloudflare
|
||||
RCLONE_CONFIG_R2_NO_CHECK_BUCKET: "true"
|
||||
RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||
RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||
RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
|
||||
run: |
|
||||
curl -fsSL https://downloads.rclone.org/rclone-current-linux-amd64.zip -o rclone.zip && unzip -jq rclone.zip '*/rclone' && chmod +x rclone
|
||||
# One JSON object per line, newest last. Served at
|
||||
# https://pkgs.omarchy.org/publish-log.jsonl
|
||||
./rclone copy R2:omarchy-pkgs/publish-log.jsonl . --s3-no-head 2>/dev/null || : > publish-log.jsonl
|
||||
jq -c . publish-record.json >> publish-log.jsonl
|
||||
./rclone copyto publish-log.jsonl R2:omarchy-pkgs/publish-log.jsonl --s3-no-head
|
||||
echo "log now has $(wc -l < publish-log.jsonl) entries"
|
||||
|
||||
- name: Comment on the merged PR
|
||||
# Only for a push: the merge commit names its PR. A dispatch runs
|
||||
# from master's head, whose PR merged something else entirely, so
|
||||
# commenting there would attach this run's report to the wrong PR.
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
pr=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" --jq '.[0].number // empty')
|
||||
if [[ -n "$pr" ]]; then
|
||||
gh pr comment "$pr" -R "${{ github.repository }}" --body-file comment.md
|
||||
echo "commented on #$pr"
|
||||
else
|
||||
echo "no PR for ${{ github.sha }} (manual dispatch?); skipping PR comment"
|
||||
fi
|
||||
result:
|
||||
needs: [changes, publish]
|
||||
if: always()
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
echo "publish result: ${{ needs.publish.result }}"
|
||||
[[ "${{ needs.publish.result }}" == "success" || "${{ needs.publish.result }}" == "skipped" ]]
|
||||
@@ -1,9 +1,11 @@
|
||||
name: Tests
|
||||
|
||||
# PR-only. Publishing on push has its own workflow and is what verifies the
|
||||
# merged tree: it resolves every package against the live channel and refuses
|
||||
# a filename that already exists with different bytes, so two PRs cannot land
|
||||
# the same version twice. A post-merge test run would only repeat the PR's.
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [master]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -30,6 +32,12 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Test PR workflow approval
|
||||
run: node --test tests/pr-workflow-approval.cjs
|
||||
|
||||
- name: Test builder images
|
||||
run: node --test tests/builder-image.cjs
|
||||
|
||||
# An Arch container for vercmp: version ordering has to be decided by
|
||||
# the same comparator pacman uses on users' machines.
|
||||
- name: Run self-tests
|
||||
@@ -40,6 +48,7 @@ jobs:
|
||||
archlinux:base-devel bash -lc '
|
||||
set -euo pipefail
|
||||
pacman -Syu --noconfirm git jq python libarchive
|
||||
python tests/oma-service-removal.py
|
||||
python tests/upstream-watch.py
|
||||
./bin/sync-upstream self-test
|
||||
./bin/sync-rebuilds --self-test
|
||||
@@ -48,4 +57,8 @@ jobs:
|
||||
./tests/partial-release.sh
|
||||
./tests/published-build-plan.sh
|
||||
./tests/settings-boot-config.sh
|
||||
./tests/controller.sh
|
||||
./tests/artifact-helpers.sh
|
||||
pacman -S --noconfirm --quiet rclone >/dev/null
|
||||
./tests/publish-artifact.sh
|
||||
'
|
||||
@@ -40,3 +40,4 @@ pkgbuilds/yay/yay/
|
||||
|
||||
# Python helpers and offline tests
|
||||
__pycache__/
|
||||
.release-verification/
|
||||
@@ -825,6 +825,45 @@ using real containers and pacman transactions. It uses the prepared builder
|
||||
image, or an image named by `TEST_BUILDER_IMAGE`; CI builds the small fixture
|
||||
image in `tests/build-isolation.Dockerfile`.
|
||||
|
||||
### Daily builder images
|
||||
|
||||
`Refresh builder images` builds fresh `edge` environments daily at 04:23 UTC,
|
||||
when their inputs change on `master`, and on manual dispatch. x86_64 and
|
||||
aarch64 build on native GitHub-hosted runners, without occupying the DO
|
||||
package-builder pool. Each candidate must pass `tests/build-isolation.sh`,
|
||||
including real package builds, before publication to
|
||||
`ghcr.io/omacom/omarchy-pkg-builder`. Only `master` in this repository can
|
||||
publish; PR workflows cannot replace the shared images.
|
||||
PRs that change image inputs also build and test both candidates on native
|
||||
runners, with a read-only token and no registry publication.
|
||||
|
||||
The compatibility tag contains the architecture, mirror, and a hash of the
|
||||
entire `build/` context, including executable bits and symlink targets but
|
||||
excluding checkout timestamps and ownership. This deliberately invalidates
|
||||
images when mounted build scripts change too. `v1` identifies the image build
|
||||
contract; change it if the invocation or compatibility rules change. Each
|
||||
successful refresh also gets a run-specific tag for diagnosis and rollback.
|
||||
A failed build, isolation test, or push leaves the previous compatible image
|
||||
selected. Scheduled builds use `--pull --no-cache` so unchanged Dockerfiles
|
||||
still pick up fresh Arch packages.
|
||||
|
||||
To build and test a candidate locally:
|
||||
|
||||
```bash
|
||||
bin/builder-image key --arch x86_64 --mirror edge
|
||||
bin/builder-image build --arch x86_64 --mirror edge --tag builder-candidate:test --fresh
|
||||
CONTAINER_ENGINE=docker TEST_BUILDER_IMAGE=builder-candidate:test tests/build-isolation.sh
|
||||
```
|
||||
|
||||
The workflow uses its repository `GITHUB_TOKEN` with `packages: write`; no
|
||||
registry PAT is needed. **First publication needs one package setting:** GHCR
|
||||
creates the package private. In the `omacom/omarchy-pkg-builder` package
|
||||
settings, change visibility to **Public**, then rerun the failed refresh job.
|
||||
The workflow checks anonymous registry access before advancing the compatible
|
||||
tag, so fork PRs will not be directed to an image they cannot pull. Subsequent
|
||||
refreshes preserve that package visibility. This change only produces images;
|
||||
package jobs keep their existing behavior until image consumption is enabled.
|
||||
|
||||
## Version Management
|
||||
|
||||
Packages are only rebuilt if:
|
||||
@@ -844,6 +883,22 @@ The repository includes GitHub workflows and systemd services for automated rele
|
||||
1. **sync-upstream.yml** (Every 6 hours): Watches direct upstream feeds and updates owned recipes. Successful package updates reach a PR even if another feed fails; failed recipes stay untouched and the workflow remains red.
|
||||
2. **sync-rebuilds.yml** (Every 6 hours): Bumps pkgrel for packages whose `rebuild_on` dependencies have moved in the official repositories and opens a PR.
|
||||
|
||||
To approve builds for an unvouched contributor's PR, apply **`build-approved`**.
|
||||
Until approval, the PR shows **Awaiting build approval** and its required
|
||||
`result` check stays pending, keeping the PR blocked from merging without
|
||||
reporting a failed build. Actual build failures and denouncements still fail.
|
||||
Applying the label triggers a package build and automatically releases GitHub's
|
||||
pending build and test workflows for that PR's current commit. The approval workflow
|
||||
runs only trusted default-branch code; package builds and tests stay in the
|
||||
ordinary PR workflows. It may take a few minutes for GitHub to register and
|
||||
release all the runs.
|
||||
|
||||
The label stays effective for that PR while attached, including later commits;
|
||||
it does not vouch for the author's other PRs. Removing it stops further label
|
||||
approvals, but does not cancel runs already released. An explicit denouncement
|
||||
in `.github/VOUCHED.td` still blocks builds. If the approval workflow times out,
|
||||
remove and reapply the label to retry.
|
||||
|
||||
#### Systemd Services
|
||||
|
||||
All four units run **every 5 minutes**, staggered by a minute each, so a push
|
||||
|
||||
@@ -92,6 +92,8 @@ while [[ $# -gt 0 ]]; do
|
||||
echo " OMARCHY_KEEP_BUILD_WORKSPACE=1 keep build-output and reuse packages already there"
|
||||
echo " OMARCHY_SKIP_BUILDER_IMAGE=1 use the existing builder image instead of building it"
|
||||
echo " OMARCHY_DEFER_RUNTIME_DEPS=true build the omarchy pair with --nodeps (transaction verified later)"
|
||||
echo " OMARCHY_PUBLISHED_REPO_URL=<url> channel to plan and resolve against when no local tree exists"
|
||||
echo " (default https://pkgs.omarchy.org; empty disables the fallback)"
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
@@ -256,6 +258,7 @@ DOCKER_ARGS=(
|
||||
-e MIRROR="$MIRROR"
|
||||
-e PACKAGES="$PACKAGES"
|
||||
-e OMARCHY_RC_PINS="${OMARCHY_RC_PINS:-}"
|
||||
-e OMARCHY_PUBLISHED_REPO_URL="${OMARCHY_PUBLISHED_REPO_URL-https://pkgs.omarchy.org}"
|
||||
-e DEFER_RUNTIME_DEPS="$DEFER_RUNTIME_DEPS"
|
||||
-e BUILD_PLAN_DIR=/build-plan
|
||||
-v "$PLAN_DIR:/build-plan"
|
||||
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Print the PR build matrix for a set of package directories as JSON: one
|
||||
# entry per package per supported architecture. Every package builds exactly
|
||||
# once, against edge, and that one artifact is what every channel ships:
|
||||
# channels are databases over a shared pool of files, and a filename must
|
||||
# mean one set of bytes. "channels" lists where the artifact is published on
|
||||
# merge: edge for everything, plus rc and stable immediately for the fast
|
||||
# ring. Eligibility comes from package_builds_for_mirror, the rule the
|
||||
# release host uses, so CI and the host cannot disagree.
|
||||
#
|
||||
# Usage: build-matrix [--arch <arch>|all] <package>...
|
||||
# Reads package names on stdin when none are given. With no --arch, every
|
||||
# architecture in CI_ARCHES (default "x86_64 aarch64") the package supports.
|
||||
# Output: {"include":[{"package":"x","arch":"x86_64","channels":"edge rc stable","publish_arches":"x86_64"},...]}
|
||||
# arch is where it builds; publish_arches lists every architecture
|
||||
# database the file goes into (all of them for arch=any).
|
||||
set -euo pipefail
|
||||
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
||||
source "$BUILD_ROOT/helpers/paths.sh"
|
||||
source "$BUILD_ROOT/helpers/package-metadata.sh"
|
||||
|
||||
ARCHES=${CI_ARCHES:-x86_64 aarch64}
|
||||
if [[ "${1:-}" == --arch ]]; then [[ $2 == all ]] || ARCHES=$2; shift 2; fi
|
||||
for a in $ARCHES; do require_valid_arch "$a"; done
|
||||
|
||||
if (( $# )); then names=("$@"); else mapfile -t names; fi
|
||||
|
||||
entries=()
|
||||
for name in "${names[@]}"; do
|
||||
[[ -n "$name" ]] || continue
|
||||
pkgdir="$PKGBUILDS_DIR/$name"
|
||||
[[ -d "$pkgdir" ]] || continue
|
||||
# skip_build packages still build on their own PR (explicit --package
|
||||
# semantics); the host's unscoped runs are what skip them.
|
||||
channels=""
|
||||
for mirror in $VALID_MIRRORS; do
|
||||
package_builds_for_mirror "$pkgdir" "$mirror" && channels="$channels $mirror"
|
||||
done
|
||||
channels=${channels# }
|
||||
[[ -n "$channels" ]] || continue
|
||||
# An arch=any package produces one architecture-independent file, so it
|
||||
# builds once, on the first architecture, and that file serves every
|
||||
# channel database of every architecture.
|
||||
if [[ " $(package_arches "$pkgdir" "${ARCHES%% *}") " == *" any "* ]]; then
|
||||
entries+=("$(jq -nc --arg p "$name" --arg a "${ARCHES%% *}" --arg c "$channels" --arg pa "$ARCHES" '{package:$p, arch:$a, channels:$c, publish_arches:$pa}')")
|
||||
continue
|
||||
fi
|
||||
for arch in $ARCHES; do
|
||||
package_supports_arch "$pkgdir" "$arch" || continue
|
||||
entries+=("$(jq -nc --arg p "$name" --arg a "$arch" --arg c "$channels" '{package:$p, arch:$a, channels:$c, publish_arches:$a}')")
|
||||
done
|
||||
done
|
||||
|
||||
printf '%s\n' "${entries[@]}" | jq -sc '{include: .}'
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# Build a reusable package environment from this checkout's own inputs.
|
||||
set -euo pipefail
|
||||
|
||||
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
||||
source "$BUILD_ROOT/helpers/paths.sh"
|
||||
|
||||
usage() {
|
||||
echo "Usage: bin/builder-image {key|build} [--arch x86_64|aarch64] [--mirror edge|rc|stable] [--tag IMAGE] [--fresh]"
|
||||
}
|
||||
|
||||
command=${1:-}
|
||||
[[ $# -eq 0 ]] || shift
|
||||
tag=""
|
||||
fresh=false
|
||||
while (( $# )); do
|
||||
case "$1" in
|
||||
--arch) ARCH=${2:?Missing architecture}; shift 2 ;;
|
||||
--mirror) MIRROR=${2:?Missing mirror}; shift 2 ;;
|
||||
--tag) tag=${2:?Missing image tag}; shift 2 ;;
|
||||
--fresh) fresh=true; shift ;;
|
||||
*) usage >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
require_valid_arch "$ARCH"
|
||||
validate_mirror "$MIRROR" || { echo "Invalid mirror: $MIRROR" >&2; exit 1; }
|
||||
case "$command" in key|build) ;; *) usage >&2; exit 1 ;; esac
|
||||
if [[ $command == key && ( -n $tag || $fresh == true ) ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Include the whole build context, conservatively including mounted build
|
||||
# scripts too. Normalize timestamps and ownership so fresh checkouts agree;
|
||||
# retain file contents, names, executable bits and symlink targets. Bump v1
|
||||
# if the image build invocation or this compatibility contract changes.
|
||||
hash=$(tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner \
|
||||
--format=gnu -cf - -C "$BUILD_DIR" . | sha256sum | cut -d' ' -f1)
|
||||
key="v1-$ARCH-$MIRROR-$hash"
|
||||
if [[ $command == key ]]; then
|
||||
echo "$key"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
||||
source "$BUILD_ROOT/helpers/docker-helpers.sh"
|
||||
check_engine
|
||||
platform=$(get_platform_arg "$ARCH")
|
||||
tag=${tag:-omarchy-pkg-builder:latest-$ARCH-$MIRROR}
|
||||
revision=$(git -C "$BUILD_ROOT" rev-parse HEAD 2>/dev/null || echo unknown)
|
||||
args=("$platform" --build-arg "MIRROR=$MIRROR"
|
||||
--label "org.omarchy.builder.key=$key"
|
||||
--label "org.opencontainers.image.source=https://github.com/omacom/omarchy-pkgs"
|
||||
--label "org.opencontainers.image.revision=$revision"
|
||||
--label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
--tag "$tag" --file "$BUILD_DIR/Dockerfile")
|
||||
if [[ $fresh == true ]]; then
|
||||
# A daily build must refresh Arch even when its Dockerfile has not changed.
|
||||
args+=(--no-cache)
|
||||
if [[ $CONTAINER_ENGINE == docker ]]; then args+=(--pull); else args+=(--pull=always); fi
|
||||
fi
|
||||
if [[ $CONTAINER_ENGINE == docker ]]; then
|
||||
docker buildx build --load "${args[@]}" "$BUILD_DIR"
|
||||
else
|
||||
podman build "${args[@]}" "$BUILD_DIR"
|
||||
fi
|
||||
Executable
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
# Publish built packages into one channel of the remote repository,
|
||||
# incrementally and immutably.
|
||||
#
|
||||
# publish-artifact --mirror <edge|rc|stable> --arch <arch> <pkg files...>
|
||||
#
|
||||
# What it does, in order:
|
||||
# 1. pull the channel's current database from the remote
|
||||
# 2. refuse if any package filename already exists on the remote
|
||||
# 3. sign each package (GPG_PRIVATE_KEY / GPG_PASSPHRASE)
|
||||
# 4. repo-add the packages into the pulled database (replaces the entry
|
||||
# for that name; nothing else in the channel is touched)
|
||||
# 5. upload packages, then signatures, then the database last
|
||||
#
|
||||
# Never overwrites: uploads use --ignore-existing for packages and the
|
||||
# pre-check in step 2 makes a same-name collision a hard failure rather than
|
||||
# a silent skip. The database is the only object rewritten, and it is
|
||||
# uploaded only after every file it references is present.
|
||||
#
|
||||
# The remote is an rclone remote (REMOTE, default the production one);
|
||||
# OMARCHY_PUBLISH_PREFIX can point a proof run at a scratch prefix.
|
||||
set -euo pipefail
|
||||
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
||||
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
||||
source "$BUILD_ROOT/helpers/paths.sh"
|
||||
|
||||
REMOTE=${REMOTE:-pkgs.omarchy.org:omarchy-pkgs}
|
||||
PREFIX=${OMARCHY_PUBLISH_PREFIX:-}
|
||||
FILES=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--mirror) MIRROR=$2; require_valid_mirror "$MIRROR"; shift 2 ;;
|
||||
--arch) ARCH=$2; require_valid_arch "$ARCH"; shift 2 ;;
|
||||
--remote) REMOTE=$2; shift 2 ;;
|
||||
-h|--help) sed -n '2,22p' "$0"; exit 0 ;;
|
||||
-*) print_error "Unknown option: $1"; exit 1 ;;
|
||||
*) FILES+=("$1"); shift ;;
|
||||
esac
|
||||
done
|
||||
(( ${#FILES[@]} )) || { print_error "No package files given"; exit 1; }
|
||||
: "${GPG_PRIVATE_KEY:?}"; GPG_PASSPHRASE=${GPG_PASSPHRASE-}
|
||||
|
||||
DEST="$REMOTE/${PREFIX:+$PREFIX/}$MIRROR/$ARCH"
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
print_header "Publish to $DEST"
|
||||
|
||||
# --- 0. sanity: every file is a package, named as makepkg names it ---------
|
||||
for f in "${FILES[@]}"; do
|
||||
[[ -f "$f" && "$f" == *.pkg.tar.* && "$f" != *.sig ]] || { print_error "Not a package file: $f"; exit 1; }
|
||||
name=$(bsdtar -xOf "$f" .PKGINFO | awk -F' = ' '$1=="pkgname"{print $2}')
|
||||
ver=$(bsdtar -xOf "$f" .PKGINFO | awk -F' = ' '$1=="pkgver"{print $2}')
|
||||
pkgarch=$(bsdtar -xOf "$f" .PKGINFO | awk -F' = ' '$1=="arch"{print $2}')
|
||||
[[ "$(basename "$f")" == "$name-$ver-$pkgarch.pkg.tar."* ]] || {
|
||||
print_error "Filename does not match PKGINFO ($name-$ver-$pkgarch): $(basename "$f")"; exit 1; }
|
||||
[[ "$pkgarch" == any || "$pkgarch" == "$ARCH" ]] || { print_error "$f is $pkgarch, publishing to $ARCH"; exit 1; }
|
||||
done
|
||||
|
||||
# --- 1. pull the current database -----------------------------------------
|
||||
mkdir -p "$WORK/repo"
|
||||
listing=$(rclone lsf "$DEST/" --s3-no-head 2>/dev/null || true)
|
||||
if grep -q '^omarchy.db.tar.zst$' <<<"$listing"; then
|
||||
rclone copy "$DEST/omarchy.db.tar.zst" "$WORK/repo" --s3-no-head
|
||||
rclone copy "$DEST/omarchy.files.tar.zst" "$WORK/repo" --s3-no-head 2>/dev/null || true
|
||||
print_info "Pulled current database ($(tar -tf "$WORK/repo/omarchy.db.tar.zst" | grep -c '/$') entries)"
|
||||
else
|
||||
print_warning "No database at $DEST — creating a new one"
|
||||
fi
|
||||
|
||||
# --- 2. same-name collisions ----------------------------------------------
|
||||
# A filename must mean one set of bytes across every channel. The same file
|
||||
# reaching a channel that already holds it (a fast-ring publish after edge,
|
||||
# a re-run, a later promotion) is fine: it is skipped on upload and only the
|
||||
# database entry is added. Different bytes under a name the channel already
|
||||
# has is the one thing this must never do.
|
||||
for f in "${FILES[@]}"; do
|
||||
b=$(basename "$f")
|
||||
grep -qxF "$b" <<<"$listing" || continue
|
||||
remote_sum=$(rclone hashsum md5 "$DEST/$b" --s3-no-head 2>/dev/null | awk '{print $1}')
|
||||
local_sum=$(md5sum "$f" | awk '{print $1}')
|
||||
if [[ -n "$remote_sum" && "$remote_sum" == "$local_sum" ]]; then
|
||||
print_info "Already published with identical bytes, adding to the database only: $b"
|
||||
else
|
||||
print_error "Already published with DIFFERENT bytes, refusing to overwrite: $b"
|
||||
echo " Bump pkgrel; published filenames are immutable."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 3. sign ---------------------------------------------------------------
|
||||
export GNUPGHOME="$WORK/gnupg"; mkdir -m 700 "$GNUPGHOME"
|
||||
echo "$GPG_PRIVATE_KEY" | gpg --batch --quiet --import
|
||||
KEY_ID=$(gpg --list-secret-keys --with-colons | awk -F: '$1=="sec"{print $5; exit}')
|
||||
[[ -n "$KEY_ID" ]] || { print_error "No secret key imported"; exit 1; }
|
||||
for f in "${FILES[@]}"; do
|
||||
cp "$f" "$WORK/repo/"
|
||||
gpg --batch --yes --pinentry-mode loopback --passphrase "$GPG_PASSPHRASE" \
|
||||
--detach-sign --no-armor --local-user "$KEY_ID" "$WORK/repo/$(basename "$f")"
|
||||
print_step "signed $(basename "$f")"
|
||||
done
|
||||
|
||||
# --- 4. repo-add (replaces the entry for each pkgname) ---------------------
|
||||
( cd "$WORK/repo" && repo-add --quiet omarchy.db.tar.zst "${FILES[@]/#*\//}" )
|
||||
ln -sf omarchy.db.tar.zst "$WORK/repo/omarchy.db"
|
||||
ln -sf omarchy.files.tar.zst "$WORK/repo/omarchy.files"
|
||||
print_info "Database now has $(tar -tf "$WORK/repo/omarchy.db.tar.zst" | grep -c '/$') entries"
|
||||
|
||||
# --- 5. upload: packages, signatures, database last -----------------------
|
||||
rclone copy "$WORK/repo" "$DEST" --s3-no-head --ignore-existing --filter '- *.sig' --filter '+ *.pkg.tar.*' --filter '- *'
|
||||
rclone copy "$WORK/repo" "$DEST" --s3-no-head --ignore-existing --filter '+ *.pkg.tar.*.sig' --filter '- *'
|
||||
# Re-verify every referenced file is really there before the db goes up.
|
||||
listing=$(rclone lsf "$DEST/" --s3-no-head)
|
||||
for f in "${FILES[@]}"; do
|
||||
b=$(basename "$f")
|
||||
grep -qxF "$b" <<<"$listing" && grep -qxF "$b.sig" <<<"$listing" || { print_error "Upload incomplete: $b"; exit 1; }
|
||||
done
|
||||
rclone copy "$WORK/repo" "$DEST" --s3-no-head --checksum --copy-links --filter '+ omarchy.db*' --filter '+ omarchy.files*' --filter '- *'
|
||||
print_success "Published ${#FILES[@]} package(s) to $DEST"
|
||||
+3
-1
@@ -129,6 +129,7 @@ RUN pacman -Syu --noconfirm && \
|
||||
wget \
|
||||
curl \
|
||||
jq \
|
||||
rclone \
|
||||
gnupg && \
|
||||
pacman -Scc --noconfirm && \
|
||||
rm -rf /var/cache/pacman/pkg/*
|
||||
@@ -146,7 +147,8 @@ RUN useradd -m -G wheel -s /bin/bash builder && \
|
||||
# be skipped at signing. Pin the extension so both architectures match.
|
||||
RUN sed -i 's/^#MAKEFLAGS=.*/MAKEFLAGS="-j$(nproc)"/' /etc/makepkg.conf && \
|
||||
sed -i 's/^COMPRESSZST=.*/COMPRESSZST=(zstd -c -z -q --threads=0 -)/' /etc/makepkg.conf && \
|
||||
sed -i "s|^PKGEXT=.*|PKGEXT='.pkg.tar.zst'|" /etc/makepkg.conf
|
||||
sed -i "s|^PKGEXT=.*|PKGEXT='.pkg.tar.zst'|" /etc/makepkg.conf && \
|
||||
sed -i 's|^#\?PACKAGER=.*|PACKAGER="Omarchy <pkgs@omarchy.org>"|' /etc/makepkg.conf
|
||||
|
||||
# Pacman wrapper that auto-resolves package conflicts (e.g. rustup vs rust).
|
||||
# makepkg only passes --noconfirm to pacman, which defaults to 'N' on conflict
|
||||
|
||||
+31
-3
@@ -26,6 +26,29 @@ DEFER_RUNTIME_DEPS=${DEFER_RUNTIME_DEPS:-false}
|
||||
|
||||
source "$HELPERS_DIR/package-metadata.sh"
|
||||
|
||||
# Where the channel's published database is read from for planning. On the
|
||||
# repository host it is the published tree itself. Anywhere else (a CI runner,
|
||||
# a fresh clone) that tree is absent, so the database is fetched from the
|
||||
# public channel and the same URL serves as pacman's dependency repository.
|
||||
# Set OMARCHY_PUBLISHED_REPO_URL= (empty) to disable the remote fallback.
|
||||
PUBLISHED_REPO_URL=${OMARCHY_PUBLISHED_REPO_URL-https://pkgs.omarchy.org}
|
||||
PUBLISHED_DB_DIR="$FINAL_OUTPUT_DIR"
|
||||
PUBLISHED_REPO_SERVER=""
|
||||
if [[ ! -f "$FINAL_OUTPUT_DIR/omarchy.db.tar.zst" && ! -f "$FINAL_OUTPUT_DIR/omarchy.db" && -n "$PUBLISHED_REPO_URL" ]]; then
|
||||
remote_channel="$PUBLISHED_REPO_URL/$MIRROR/$ARCH"
|
||||
remote_db_dir=$(mktemp -d /tmp/omarchy-published.XXXXXX) || exit 1
|
||||
# Cache-bust: the channel sits behind a CDN that serves a stale database
|
||||
# for a while after a sync.
|
||||
if curl -fsSL "$remote_channel/omarchy.db.tar.zst?$(date +%s)" -o "$remote_db_dir/omarchy.db.tar.zst"; then
|
||||
PUBLISHED_DB_DIR="$remote_db_dir"
|
||||
PUBLISHED_REPO_SERVER="$remote_channel"
|
||||
echo "==> No local published tree; planning against $remote_channel"
|
||||
else
|
||||
rm -rf "$remote_db_dir"
|
||||
echo "==> No local published tree and $remote_channel is unavailable; treating the channel as empty"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $DEFER_RUNTIME_DEPS != "false" && $DEFER_RUNTIME_DEPS != "true" ]]; then
|
||||
echo "DEFER_RUNTIME_DEPS must be true or false" >&2
|
||||
exit 1
|
||||
@@ -118,10 +141,15 @@ if [[ "$DRY_RUN" != true ]]; then
|
||||
fi
|
||||
touch "$BUILD_PLAN_DIR/repository-initialized" || exit 1
|
||||
|
||||
# Add omarchy repo if it has a database (stable packages)
|
||||
# Add omarchy repo if it has a database (stable packages). The local tree
|
||||
# is trusted as-is; the public channel is verified against the omarchy
|
||||
# keyring the image already carries.
|
||||
if [[ -f "$FINAL_OUTPUT_DIR/omarchy.db.tar.zst" ]] || [[ -f "$FINAL_OUTPUT_DIR/omarchy.db" ]]; then
|
||||
sudo sed -i "/^\[core\]$/i [omarchy]\nSigLevel = Optional TrustAll\nServer = file://$FINAL_OUTPUT_DIR\n" /etc/pacman.conf
|
||||
echo " -> omarchy (priority 2): $FINAL_OUTPUT_DIR"
|
||||
elif [[ -n "$PUBLISHED_REPO_SERVER" ]]; then
|
||||
sudo sed -i "/^\[core\]$/i [omarchy]\nSigLevel = Required DatabaseOptional\nServer = $PUBLISHED_REPO_SERVER\n" /etc/pacman.conf
|
||||
echo " -> omarchy (priority 2): $PUBLISHED_REPO_SERVER"
|
||||
fi
|
||||
|
||||
# Sync pacman database
|
||||
@@ -159,10 +187,10 @@ LOCAL_VERSION_CACHE_LOADED=false
|
||||
LOCAL_VERSION_CACHE_DB=""
|
||||
|
||||
load_local_versions() {
|
||||
local db="$FINAL_OUTPUT_DIR/omarchy.db.tar.zst"
|
||||
local db="$PUBLISHED_DB_DIR/omarchy.db.tar.zst"
|
||||
|
||||
if [[ ! -f "$db" ]]; then
|
||||
db="$FINAL_OUTPUT_DIR/omarchy.db"
|
||||
db="$PUBLISHED_DB_DIR/omarchy.db"
|
||||
fi
|
||||
|
||||
[[ -f "$db" ]] || return 0
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# CI spike: build PRs on ephemeral DigitalOcean droplets
|
||||
|
||||
Status: spike. Nothing here publishes. The repository host keeps building and
|
||||
signing on merge exactly as before.
|
||||
|
||||
## Pieces
|
||||
|
||||
- `.github/workflows/build-pr.yml` — on a PR touching `pkgbuilds/**`, one job
|
||||
per changed package on runners labelled `omarchy-builder`. Uploads the
|
||||
unsigned `.pkg.tar.zst` as a workflow artifact (7 days).
|
||||
- `runner-cloud-init.yaml` — Ubuntu 24.04 user-data: docker + buildx, the
|
||||
GitHub runner registered `--ephemeral`, runs one job, powers off.
|
||||
- `controller.sh` — systemd timer every minute on a small always-on droplet.
|
||||
Polls for queued jobs with our label, creates one g5-32vcpu-64gb-50gb droplet (ric1) per job up
|
||||
to `MAX_DROPLETS`, deletes droplets that are powered off or older than
|
||||
`MAX_AGE_MINUTES`. No inbound endpoint. Plain curl against both APIs, no
|
||||
doctl and no gh: a token in the environment cannot pick the wrong account
|
||||
the way a saved doctl context can. Needs curl and jq.
|
||||
`tests/controller.sh` exercises every decision against canned responses.
|
||||
- `controller-box/` — the always-on droplet: unit, timer, env template,
|
||||
cloud-init, and `create.sh` to stand it up with one API call.
|
||||
|
||||
## Standing up the controller box
|
||||
|
||||
DIGITALOCEAN_TOKEN=<omarchy account> GITHUB_TOKEN=<fine-grained PAT> \
|
||||
REPO=omacom/omarchy-pkgs ci/controller-box/create.sh <branch>
|
||||
|
||||
The GitHub PAT is fine-grained, scoped to the one repo: Actions read,
|
||||
Administration read+write (registration tokens). The DO token is baked into
|
||||
the box's env file, so it is the account that pays for builder droplets.
|
||||
Watch it with `journalctl -u omarchy-controller -f` on the box.
|
||||
|
||||
## What the spike proved (2026-09-17, fork ryanrhughes/omarchy-pkgs)
|
||||
|
||||
- `bin/build` works from a bare clone: with no local published tree it
|
||||
plans against and resolves from `https://pkgs.omarchy.org/<mirror>/<arch>`.
|
||||
- Droplet create → runner registered: ~70 s. omarchy-fish PR job: 2 min
|
||||
including the builder image build. Droplet powers off after the job.
|
||||
- linux-omarchy on a c-32 droplet: 30 min wall clock for the build job
|
||||
(23:39 → 00:09), 254 MB artifact. Cold start ~90 s before the job began.
|
||||
- A PR whose PKGBUILD fails to build turns the required check red and GitHub
|
||||
refuses the merge (`mergeStateStatus=BLOCKED`, `gh pr merge` refuses
|
||||
without `--admin`).
|
||||
- Controller: one queued job + one busy droplet ⇒ creates exactly one more;
|
||||
reaps powered-off droplets on the next tick.
|
||||
|
||||
## Not done (required before this touches the real repo)
|
||||
|
||||
- Tooling from base: check out master's `bin/ helpers/ build/` and overlay
|
||||
only the PR's `pkgbuilds/<name>`; today a PR can edit the build script
|
||||
and it runs on the droplet. The vouch gate limits who can do that, not
|
||||
what they can do.
|
||||
- DigitalOcean cloud firewall on the `omarchy-builder` tag: no inbound, no
|
||||
egress to private ranges or the metadata address.
|
||||
- A fine-grained GitHub token for the real repository (the one on the
|
||||
controller box is scoped to the fork), and the publish environment's
|
||||
secrets set there.
|
||||
- Disable the host's auto-release timers for any channel CI publishes to,
|
||||
so two writers never touch one database.
|
||||
|
||||
## Done since the spike README was first written
|
||||
|
||||
- Controller as a systemd timer on its own droplet, plain curl, self-test.
|
||||
- Build once against edge; one artifact per package per architecture,
|
||||
published into every channel it belongs to (fast ring: all three at
|
||||
once). arch=any builds once for every architecture database.
|
||||
- Publish is incremental and immutable: pull the channel db, refuse
|
||||
different bytes under an existing name, accept identical bytes, upload
|
||||
packages then signatures then the db.
|
||||
- aarch64 under QEMU with credential-preserving binfmt.
|
||||
- Vouch gate: collaborators, `.github/VOUCHED.td`, or the `build-approved`
|
||||
label; denounced authors cannot be overridden by the label.
|
||||
- Tests run on PRs only; `result`, `self-tests`, `build-isolation` are the
|
||||
required checks with strict up-to-date branches.
|
||||
|
||||
## Cleanup
|
||||
|
||||
doctl compute droplet list --tag-name omarchy-builder
|
||||
doctl compute droplet delete -f <id>
|
||||
@@ -0,0 +1,45 @@
|
||||
#cloud-config
|
||||
# The always-on controller droplet (smallest size is fine). Clones the repo
|
||||
# for ci/controller.sh, installs the unit and timer, and starts polling.
|
||||
#
|
||||
# Substitute before use:
|
||||
# __REPO_URL__ https://github.com/omacom/omarchy-pkgs.git
|
||||
# __BRANCH__ branch carrying ci/ (master once merged)
|
||||
# __ENV_B64__ base64 of a filled-in controller.env.example
|
||||
# __SSH_KEYS_JSON__ JSON array of public keys authorized for root
|
||||
package_update: true
|
||||
packages: [curl, jq, git]
|
||||
|
||||
# Root stays reachable by key so the journal can be read. Two things stand
|
||||
# in the way on DO images: disable_root rewrites root's keys into a stub, and
|
||||
# with no account ssh key attached DO expires root's password, which makes
|
||||
# sshd refuse every non-interactive session with "password change required".
|
||||
disable_root: false
|
||||
chpasswd:
|
||||
expire: false
|
||||
ssh_authorized_keys: __SSH_KEYS_JSON__
|
||||
|
||||
users:
|
||||
- name: controller
|
||||
shell: /bin/bash
|
||||
|
||||
write_files:
|
||||
# defer: write after the users module has created the controller group,
|
||||
# otherwise chown to root:controller fails and the unit cannot read this.
|
||||
- path: /etc/omarchy-controller.env
|
||||
permissions: "0640"
|
||||
owner: root:controller
|
||||
encoding: b64
|
||||
defer: true
|
||||
content: __ENV_B64__
|
||||
|
||||
runcmd:
|
||||
- chage -d "$(date +%F)" -M -1 root
|
||||
- chown root:controller /etc/omarchy-controller.env && chmod 0640 /etc/omarchy-controller.env
|
||||
- git clone --depth 1 --branch __BRANCH__ __REPO_URL__ /opt/omarchy-pkgs
|
||||
- mkdir -p /run/omarchy-controller && chown controller:controller /run/omarchy-controller
|
||||
- echo "d /run/omarchy-controller 0755 controller controller -" > /etc/tmpfiles.d/omarchy-controller.conf
|
||||
# runcmd is executed by /bin/sh: no brace expansion.
|
||||
- cp /opt/omarchy-pkgs/ci/controller-box/omarchy-controller.service /opt/omarchy-pkgs/ci/controller-box/omarchy-controller.timer /etc/systemd/system/
|
||||
- systemctl daemon-reload
|
||||
- systemctl enable --now omarchy-controller.timer
|
||||
@@ -0,0 +1,15 @@
|
||||
# /etc/omarchy-controller.env — mode 0600, owned by root, read by systemd.
|
||||
DIGITALOCEAN_TOKEN=dop_v1_...
|
||||
# Fine-grained PAT scoped to the repo: Actions: read, Administration: read+write
|
||||
GITHUB_TOKEN=github_pat_...
|
||||
REPO=omacom/omarchy-pkgs
|
||||
LABEL=omarchy-builder
|
||||
TAG=omarchy-builder
|
||||
REGION=ric1
|
||||
SIZE=g5-32vcpu-64gb-50gb
|
||||
MAX_DROPLETS=6
|
||||
MAX_AGE_MINUTES=200
|
||||
LOCK=/run/omarchy-controller/lock
|
||||
# Operator public keys for root on every builder droplet (JSON array).
|
||||
# create.sh fills this from the operators' GitHub keys.
|
||||
SSH_KEYS_JSON=[]
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Create the controller droplet with plain curl. Run from a laptop, once.
|
||||
#
|
||||
# DIGITALOCEAN_TOKEN=... GITHUB_TOKEN=... ci/controller-box/create.sh [branch]
|
||||
#
|
||||
# The DO token given here is baked into the box's env file, so it must be the
|
||||
# token for the account that should pay for builder droplets.
|
||||
set -euo pipefail
|
||||
here=$(dirname "$0")
|
||||
: "${DIGITALOCEAN_TOKEN:?}" "${GITHUB_TOKEN:?}"
|
||||
REPO=${REPO:-omacom/omarchy-pkgs}
|
||||
BRANCH=${1:-master}
|
||||
REGION=${REGION:-ric1}
|
||||
NAME=${NAME:-omarchy-controller}
|
||||
# Optional DO ssh key ids as a JSON array, e.g. SSH_KEYS='[123]', for reading
|
||||
# the journal while bringing the box up. Not needed once it works.
|
||||
SSH_KEYS=${SSH_KEYS:-[]}
|
||||
# Public keys authorized for root: the operators' GitHub keys, fetched at
|
||||
# creation so the box never depends on an ssh_key API scope. Override with
|
||||
# ADMIN_GITHUB_USERS.
|
||||
ADMIN_GITHUB_USERS=${ADMIN_GITHUB_USERS:-ryanrhughes dhh}
|
||||
ssh_keys_json=$(for u in $ADMIN_GITHUB_USERS; do curl -fsS "https://github.com/$u.keys"; done | jq -R . | jq -sc .)
|
||||
[[ $(jq length <<<"$ssh_keys_json") -gt 0 ]] || { echo "no ssh keys fetched for $ADMIN_GITHUB_USERS" >&2; exit 1; }
|
||||
|
||||
env_file=$(sed -e "s|^DIGITALOCEAN_TOKEN=.*|DIGITALOCEAN_TOKEN=$DIGITALOCEAN_TOKEN|" \
|
||||
-e "s|^GITHUB_TOKEN=.*|GITHUB_TOKEN=$GITHUB_TOKEN|" \
|
||||
-e "s|^REPO=.*|REPO=$REPO|" \
|
||||
-e "s|^SSH_KEYS_JSON=.*|SSH_KEYS_JSON=$ssh_keys_json|" "$here/controller.env.example")
|
||||
userdata=$(sed -e "s|__REPO_URL__|https://github.com/$REPO.git|" -e "s|__BRANCH__|$BRANCH|" \
|
||||
-e "s|__ENV_B64__|$(printf '%s\n' "$env_file" | base64 -w0)|" \
|
||||
-e "s|__SSH_KEYS_JSON__|$ssh_keys_json|" "$here/cloud-init.yaml")
|
||||
body=$(jq -n --arg name "$NAME" --arg region "$REGION" --arg ud "$userdata" --argjson keys "$SSH_KEYS" \
|
||||
'{name:$name, region:$region, size:"s-1vcpu-1gb", image:"ubuntu-24-04-x64", tags:["omarchy-controller"], user_data:$ud, ssh_keys:$keys}')
|
||||
|
||||
# Refuse to create a second one.
|
||||
existing=$(curl -fsS -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
|
||||
"https://api.digitalocean.com/v2/droplets?tag_name=omarchy-controller" | jq '.droplets | length')
|
||||
if (( existing > 0 )); then echo "a controller droplet already exists" >&2; exit 1; fi
|
||||
|
||||
curl -fsS -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" -H "Content-Type: application/json" \
|
||||
-X POST -d "$body" https://api.digitalocean.com/v2/droplets | jq -r '"created \(.droplet.name) id=\(.droplet.id)"'
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Provision ephemeral omarchy-builder runner droplets for queued jobs
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=controller
|
||||
EnvironmentFile=/etc/omarchy-controller.env
|
||||
ExecStart=/opt/omarchy-pkgs/ci/controller.sh
|
||||
# The reaper's safety net is time, not state; a hung tick must not hold the lock.
|
||||
TimeoutStartSec=240
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run the omarchy-builder controller every minute
|
||||
|
||||
[Timer]
|
||||
OnBootSec=1min
|
||||
OnUnitActiveSec=1min
|
||||
AccuracySec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
# Droplet-per-job controller for the omarchy-builder runner pool.
|
||||
#
|
||||
# Run from a systemd timer every minute on a small always-on droplet. No
|
||||
# inbound endpoint: it polls GitHub for queued jobs wanting our label, creates
|
||||
# one ephemeral droplet per job (up to MAX_DROPLETS), and deletes droplets
|
||||
# that have powered off or exceeded MAX_AGE_MINUTES. The reaper does not
|
||||
# trust its own bookkeeping: it lists by tag and acts on what DigitalOcean
|
||||
# reports.
|
||||
#
|
||||
# Talks to both APIs with curl. No doctl: its saved contexts silently choose
|
||||
# an account; a token in the environment cannot. Needs curl and jq.
|
||||
#
|
||||
# Environment:
|
||||
# DIGITALOCEAN_TOKEN DO API token for the account that pays for droplets
|
||||
# GITHUB_TOKEN fine-grained PAT: Actions read, Administration write
|
||||
# REPO owner/name
|
||||
set -euo pipefail
|
||||
|
||||
REPO=${REPO:?owner/name}
|
||||
: "${DIGITALOCEAN_TOKEN:?}" "${GITHUB_TOKEN:?}"
|
||||
LABEL=${LABEL:-omarchy-builder}
|
||||
TAG=${TAG:-omarchy-builder}
|
||||
REGION=${REGION:-ric1}
|
||||
SIZE=${SIZE:-g5-32vcpu-64gb-50gb}
|
||||
IMAGE=${IMAGE:-ubuntu-24-04-x64}
|
||||
MAX_DROPLETS=${MAX_DROPLETS:-4}
|
||||
MAX_AGE_MINUTES=${MAX_AGE_MINUTES:-200}
|
||||
RUNNER_VERSION=${RUNNER_VERSION:-2.337.0}
|
||||
CLOUD_INIT=${CLOUD_INIT:-$(dirname "$0")/runner-cloud-init.yaml}
|
||||
# Operator public keys authorized on every builder (JSON array of strings).
|
||||
# The box's env file carries them; empty means no root login.
|
||||
SSH_KEYS_JSON=${SSH_KEYS_JSON:-[]}
|
||||
LOCK=${LOCK:-/tmp/omarchy-controller.lock}
|
||||
|
||||
log() { echo "$(date '+%F %T') $*"; }
|
||||
|
||||
# The only two places the outside world is touched. The self-test overrides
|
||||
# both, so every decision below is exercised against canned responses.
|
||||
do_api() { # do_api <path> [curl args...]
|
||||
local path=$1; shift
|
||||
curl -fsS -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
|
||||
-H "Content-Type: application/json" "https://api.digitalocean.com/v2/$path" "$@"
|
||||
}
|
||||
gh_api() { # gh_api <path> [curl args...]
|
||||
local path=$1; shift
|
||||
curl -fsS -H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
-H "Accept: application/vnd.github+json" "https://api.github.com/$path" "$@"
|
||||
}
|
||||
|
||||
# --- reap ------------------------------------------------------------------
|
||||
reap() {
|
||||
local now id status created age
|
||||
now=$(date +%s)
|
||||
while read -r id status created; do
|
||||
[[ -n "$id" ]] || continue
|
||||
age=$(( (now - $(date -d "$created" +%s)) / 60 ))
|
||||
if [[ $status == off ]] || (( age > MAX_AGE_MINUTES )); then
|
||||
log "deleting droplet $id (status=$status age=${age}m)"
|
||||
do_api "droplets/$id" -X DELETE
|
||||
fi
|
||||
done < <(do_api "droplets?tag_name=$TAG&per_page=200" |
|
||||
jq -r '.droplets[] | "\(.id) \(.status) \(.created_at)"')
|
||||
}
|
||||
|
||||
# --- demand ----------------------------------------------------------------
|
||||
queued_jobs() {
|
||||
local run
|
||||
gh_api "repos/$REPO/actions/runs?status=queued&per_page=50" --get \
|
||||
| jq -r '.workflow_runs[].id' |
|
||||
while read -r run; do
|
||||
gh_api "repos/$REPO/actions/runs/$run/jobs" \
|
||||
| jq -r --arg l "$LABEL" '.jobs[] | select(.status=="queued") | select(.labels | index($l)) | .id'
|
||||
done | wc -l
|
||||
}
|
||||
|
||||
live_droplets() {
|
||||
do_api "droplets?tag_name=$TAG&per_page=200" | jq '[.droplets[] | select(.status != "off")] | length'
|
||||
}
|
||||
|
||||
busy_runners() {
|
||||
gh_api "repos/$REPO/actions/runners?per_page=100" \
|
||||
| jq --arg l "$LABEL" '[.runners[] | select(.busy) | select(any(.labels[]; .name == $l))] | length'
|
||||
}
|
||||
|
||||
# --- create ----------------------------------------------------------------
|
||||
create_droplet() {
|
||||
local token userdata name body
|
||||
token=$(gh_api "repos/$REPO/actions/runners/registration-token" -X POST | jq -r .token)
|
||||
userdata=$(sed -e "s|__REPO__|$REPO|g" -e "s|__RUNNER_TOKEN__|$token|g" \
|
||||
-e "s|__RUNNER_LABELS__|$LABEL|g" -e "s|__RUNNER_VERSION__|$RUNNER_VERSION|g" \
|
||||
-e "s|__SSH_KEYS_JSON__|$SSH_KEYS_JSON|" "$CLOUD_INIT")
|
||||
name="$TAG-$(date +%s)-$RANDOM"
|
||||
body=$(jq -n --arg name "$name" --arg region "$REGION" --arg size "$SIZE" --arg image "$IMAGE" \
|
||||
--arg tag "$TAG" --arg ud "$userdata" \
|
||||
'{name:$name, region:$region, size:$size, image:$image, tags:[$tag], user_data:$ud, monitoring:false}')
|
||||
log "creating $name ($SIZE)"
|
||||
do_api droplets -X POST -d "$body" | jq -r '"created droplet \(.droplet.id)"'
|
||||
}
|
||||
|
||||
controller_tick() {
|
||||
reap
|
||||
local queued live busy available need room
|
||||
queued=$(queued_jobs)
|
||||
live=$(live_droplets)
|
||||
busy=$(busy_runners)
|
||||
# A live droplet whose runner is busy is spoken for. Only droplets still
|
||||
# booting or listening can absorb a queued job.
|
||||
available=$(( live - busy )); (( available < 0 )) && available=0
|
||||
need=$(( queued - available ))
|
||||
(( need > 0 )) || return 0
|
||||
room=$(( MAX_DROPLETS - live ))
|
||||
(( need > room )) && need=$room
|
||||
if (( need <= 0 )); then
|
||||
log "at cap ($live/$MAX_DROPLETS, $busy busy) with $queued queued"
|
||||
return 0
|
||||
fi
|
||||
local i
|
||||
for (( i = 0; i < need; i++ )); do create_droplet; done
|
||||
}
|
||||
|
||||
if [[ "${CONTROLLER_LIBRARY_ONLY:-}" != 1 ]]; then
|
||||
exec 9>"$LOCK"; flock -n 9 || exit 0
|
||||
controller_tick
|
||||
fi
|
||||
@@ -0,0 +1,81 @@
|
||||
#cloud-config
|
||||
# Ephemeral GitHub Actions runner for omarchy-pkgs package builds.
|
||||
#
|
||||
# Boots an Ubuntu droplet, installs docker and the runner, registers ONCE with
|
||||
# --ephemeral, runs exactly one job, then powers off. The controller (or the
|
||||
# reaper) deletes the powered-off droplet. Nothing here holds a long-lived
|
||||
# credential: the registration token is single-use and expires in an hour.
|
||||
#
|
||||
# Substitute before use:
|
||||
# __REPO__ owner/name
|
||||
# __RUNNER_TOKEN__ registration token (gh api -X POST repos/O/R/actions/runners/registration-token)
|
||||
# __RUNNER_LABELS__ e.g. omarchy-builder
|
||||
# __RUNNER_VERSION__ e.g. 2.329.0
|
||||
|
||||
# Operators can reach a builder by key while it lives; it powers off after
|
||||
# one job anyway. Keys are substituted by the controller (__SSH_KEYS_JSON__).
|
||||
disable_root: false
|
||||
chpasswd:
|
||||
expire: false
|
||||
ssh_authorized_keys: __SSH_KEYS_JSON__
|
||||
|
||||
package_update: true
|
||||
packages:
|
||||
- docker.io
|
||||
- docker-buildx
|
||||
- unzip
|
||||
- git
|
||||
- curl
|
||||
- jq
|
||||
- rsync
|
||||
|
||||
users:
|
||||
- name: runner
|
||||
groups: [docker]
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
|
||||
write_files:
|
||||
# defer: write after users/groups exist, so /home/runner is created by
|
||||
# useradd (owned by runner) rather than by this module as root.
|
||||
- path: /home/runner/start.sh
|
||||
permissions: "0755"
|
||||
owner: runner:runner
|
||||
defer: true
|
||||
content: |
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
cd /home/runner
|
||||
mkdir -p actions-runner && cd actions-runner
|
||||
arch=$(uname -m); [[ $arch == x86_64 ]] && arch=x64
|
||||
curl -fsSL -o runner.tgz \
|
||||
"https://github.com/actions/runner/releases/download/v__RUNNER_VERSION__/actions-runner-linux-${arch}-__RUNNER_VERSION__.tar.gz"
|
||||
tar xzf runner.tgz && rm runner.tgz
|
||||
./config.sh --unattended --ephemeral \
|
||||
--url "https://github.com/__REPO__" \
|
||||
--token "__RUNNER_TOKEN__" \
|
||||
--name "do-$(hostname)" \
|
||||
--labels "__RUNNER_LABELS__" \
|
||||
--replace
|
||||
./run.sh
|
||||
# One job done. Power off; the controller deletes powered-off droplets.
|
||||
sudo poweroff
|
||||
|
||||
runcmd:
|
||||
# With no account ssh key attached, DO expires root's password, and sshd
|
||||
# then refuses every non-interactive session. Clear it first so operators
|
||||
# can read the logs of a builder that never registers.
|
||||
- chage -d "$(date +%F)" -M -1 root
|
||||
- systemctl enable --now docker
|
||||
# aarch64 builds run under user-mode emulation (DO has no arm droplets).
|
||||
# Register QEMU with the F and C flags via tonistiigi/binfmt, exactly as
|
||||
# helpers/docker-helpers.sh setup_qemu does. Ubuntu's qemu-user-static
|
||||
# registers without C, so sudo inside the emulated container fails with
|
||||
# "effective uid is not 0"; multiarch/qemu-user-static is abandoned at QEMU
|
||||
# 7.2, under which qmake's compiler probe returns nothing on current gcc
|
||||
# ("failed to parse default include paths", PR #517). Pin the emulator
|
||||
# version: the tag is the only thing that decides what every aarch64 build
|
||||
# runs under. Best-effort: an x86-only job never needs it.
|
||||
- docker run --rm --privileged docker.io/tonistiigi/binfmt:qemu-v10.2.3-68 --uninstall qemu-aarch64 --install arm64 || true
|
||||
- chown -R runner:runner /home/runner
|
||||
- sudo -u runner /home/runner/start.sh > /home/runner/runner.log 2>&1
|
||||
@@ -168,6 +168,8 @@ in `origin` and has no effect on release selection.
|
||||
|
||||
These packages were already excluded from automatic AUR updates. The migration preserves that policy.
|
||||
|
||||
`linux-firmware-cirrus` is a deliberate hold: a self-retiring shim that ships Arch's linux-firmware-cirrus 20260910-2 payload to stable while stable's Arch snapshot is on 20260810-2 (Dell XPS 13 DX13260 / 1028:0e54 speaker firmware). It is versioned 20260810-3 so the genuine Arch package supersedes it as soon as the snapshot advances; bumping it to the Arch version would defeat that. Delete the recipe once stable's snapshot carries linux-firmware >= 20260910.
|
||||
|
||||
## Package-specific boundaries
|
||||
|
||||
- NVIDIA watches remain on the 580 driver branch.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
# Package files cross from a PR build to publish.yml as one GitHub Actions
|
||||
# artifact. actions/upload-artifact rejects any path containing ':', and a
|
||||
# package with an epoch is named `name-1:ver-rel-arch.pkg.tar.zst` by
|
||||
# makepkg. So the files ride inside a tar with a plain name and keep their
|
||||
# own names untouched: pacman clients and bin/publish-artifact both rely on
|
||||
# the filename matching PKGINFO.
|
||||
#
|
||||
# Both functions run under the workflow's `bash -e`: nothing in them may
|
||||
# return non-zero except the final failure.
|
||||
|
||||
# package_files <dir>: the *.pkg.tar.zst directly in <dir>, one per line.
|
||||
# Signatures and the scratch database next to them are not packages.
|
||||
package_files() {
|
||||
local f
|
||||
for f in "$1"/*.pkg.tar.zst; do
|
||||
[[ -e "$f" ]] && printf '%s\n' "$f"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# pack_packages <dir> <tar>: every package in <dir> into <tar>.
|
||||
pack_packages() {
|
||||
local dir=$1 out=$2 files=()
|
||||
mapfile -t files < <(package_files "$dir")
|
||||
(( ${#files[@]} )) || { echo "pack_packages: no *.pkg.tar.zst in $dir" >&2; return 1; }
|
||||
tar -cf "$out" -C "$dir" -- "${files[@]##*/}"
|
||||
}
|
||||
|
||||
# unpack_packages <artifact dir> <dest>: the packages an unzipped artifact
|
||||
# carried, into <dest>. Packed artifacts hold packages.tar; artifacts from
|
||||
# builds before packing hold the bare files. The bare form can go once
|
||||
# those artifacts have expired (7-day retention).
|
||||
unpack_packages() {
|
||||
local src=$1 dest=$2 files=()
|
||||
mkdir -p "$dest"
|
||||
if [[ -f "$src/packages.tar" ]]; then
|
||||
tar -xf "$src/packages.tar" -C "$dest"
|
||||
return 0
|
||||
fi
|
||||
mapfile -t files < <(package_files "$src")
|
||||
(( ${#files[@]} )) || { echo "unpack_packages: nothing to unpack in $src" >&2; return 1; }
|
||||
cp -- "${files[@]}" "$dest/"
|
||||
}
|
||||
@@ -91,8 +91,19 @@ setup_qemu() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Register emulators for builds whose target differs from the host.
|
||||
if ! "$CONTAINER_ENGINE" run --rm --privileged docker.io/multiarch/qemu-user-static --reset -p yes --credential yes >/dev/null 2>&1; then
|
||||
# Register emulators for builds whose target differs from the host, with
|
||||
# the F and C flags (tonistiigi/binfmt always sets both). The image tag pins
|
||||
# the QEMU version every emulated build runs under; multiarch/qemu-user-static
|
||||
# stopped at QEMU 7.2, which breaks qmake's compiler probe on current gcc.
|
||||
# Keep ci/runner-cloud-init.yaml on the same tag. Uninstall first: install
|
||||
# leaves an existing registration (an older emulator) in place and exits 0.
|
||||
local platform_arch
|
||||
case "$target_arch" in
|
||||
aarch64) platform_arch=arm64 ;;
|
||||
x86_64) platform_arch=amd64 ;;
|
||||
*) platform_arch="$target_arch" ;;
|
||||
esac
|
||||
if ! "$CONTAINER_ENGINE" run --rm --privileged docker.io/tonistiigi/binfmt:qemu-v10.2.3-68 --uninstall "qemu-$target_arch" --install "$platform_arch" >/dev/null 2>&1; then
|
||||
print_error "Failed to set up QEMU emulation"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Maintainer: Bjarne Øverli <bjarne@oever.li>
|
||||
pkgname=aether
|
||||
pkgver=4.29.8
|
||||
pkgver=4.30.0
|
||||
pkgrel=1
|
||||
pkgdesc='Desktop theming application - extract colors from wallpapers and apply cohesive themes'
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -10,9 +10,9 @@ depends=('webkit2gtk-4.1' 'gtk3')
|
||||
source=("aether-${pkgver}.tar.gz::https://github.com/omacom/aether/archive/refs/tags/v${pkgver}.tar.gz")
|
||||
source_x86_64=("aether-linux-amd64-${pkgver}::https://github.com/omacom/aether/releases/download/v${pkgver}/aether-linux-amd64")
|
||||
source_aarch64=("aether-linux-arm64-${pkgver}::https://github.com/omacom/aether/releases/download/v${pkgver}/aether-linux-arm64")
|
||||
sha256sums=('b83e0eeb1332b4ed655389a051d5b9b14a3e109968b7f278005e52c5e69a1e9c')
|
||||
sha256sums_x86_64=('d3d2d07b32da7a495221ed271ee66f4a1e344c91dcec9b267ec0a74ab6e36462')
|
||||
sha256sums_aarch64=('ffcfd23d0375a3f0c0ce014821cc5e1670f2e061c35e991340e75352dac9b731')
|
||||
sha256sums=('f67c8d2c6f27f67a755bc279ece5ddb194f1bb165648280b9a7be86904d36ff5')
|
||||
sha256sums_x86_64=('75bda600ddd3ecab3338de5c0c5d5e2c9f08cfc0c465b63f8e6cb9c5cb60d68e')
|
||||
sha256sums_aarch64=('a91d800736def74d86e19d8acbecc4bda3d7c3e64fb95273f809707104c3a5bc')
|
||||
noextract=("aether-linux-amd64-${pkgver}" "aether-linux-arm64-${pkgver}")
|
||||
|
||||
package() {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": "local",
|
||||
"release_ring": "fast",
|
||||
"origin": {
|
||||
"aur": "bambustudio-bin",
|
||||
"commit": "b962c12d14873f94669e0e256a444f957b1843cd"
|
||||
},
|
||||
"upstream": {
|
||||
"watch": {
|
||||
"regex": "https://api.github.com/repos/bambulab/BambuStudio/releases/latest",
|
||||
"pattern": "\"name\"\\s*:\\s*\"BambuStudio_ubuntu24\\.04-v(?P<version>[0-9]+(?:\\.[0-9]+)*)-(?P<build>[0-9]+)\\.AppImage\"",
|
||||
"variables": {
|
||||
"_build": "{build}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Name=Bambu Studio
|
||||
GenericName=3D Printing Software
|
||||
Comment=Slicer for Bambu Lab and other 3D printers
|
||||
Exec=/usr/bin/bambu-studio %U
|
||||
Icon=BambuStudio
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics;3DGraphics;Engineering;
|
||||
MimeType=x-scheme-handler/bambustudio;x-scheme-handler/bambustudioopen;model/stl;model/3mf;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;application/x-amf;
|
||||
Keywords=3D;Printing;Slicer;gcode;stl;3mf;
|
||||
StartupWMClass=bambu-studio
|
||||
@@ -0,0 +1,48 @@
|
||||
# Maintainer: goll <adrian.goll+aur[at]gmail>
|
||||
# Contributor: George Woodall <georgewoodall82@gmail.com>
|
||||
pkgname=bambustudio-bin
|
||||
pkgver=02.08.02.61
|
||||
pkgrel=1
|
||||
pkgdesc="PC Software for BambuLab's 3D printers"
|
||||
arch=("x86_64")
|
||||
url="https://github.com/bambulab/BambuStudio"
|
||||
license=('AGPL-3.0-only')
|
||||
conflicts=('bambustudio' 'bambustudio-git')
|
||||
depends=('cairo' 'dbus' 'fontconfig' 'gcc-libs' 'glib2' 'glibc'
|
||||
'gst-libav' 'gst-plugins-base-libs' 'gstreamer' 'gtk3' 'libglvnd'
|
||||
'libx11' 'mesa' 'pango' 'wayland' 'webkit2gtk-4.1')
|
||||
makedepends=('7zip')
|
||||
options=('!strip' '!debug')
|
||||
# The upstream watch updates the timestamp together with pkgver.
|
||||
_build=20260820225108
|
||||
source=("bambustudio-${pkgver}.AppImage::https://github.com/bambulab/BambuStudio/releases/download/v${pkgver}/BambuStudio_ubuntu24.04-v${pkgver}-${_build}.AppImage"
|
||||
"BambuStudio.desktop"
|
||||
"bambu-studio")
|
||||
noextract=("bambustudio-${pkgver}.AppImage")
|
||||
sha256sums=(
|
||||
'd501b103fac5424513ec0e8d6bc145fb30719de2c7d94d7320d723740c81a7fd'
|
||||
'f10718a8b201cad64800746fe8167ccc032c545d05f7ad8caa99eb5fb975f2a1'
|
||||
'a3a5c8f6a8b287e42b93957e9602621923c766e0b6a3f10c14eca10b023b15f2'
|
||||
)
|
||||
|
||||
prepare() {
|
||||
# Read the embedded SquashFS without executing or modifying the AppImage.
|
||||
rm -rf "$srcdir/squashfs-root"
|
||||
7z x "$srcdir/bambustudio-${pkgver}.AppImage" -o"$srcdir/squashfs-root" >/dev/null
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/squashfs-root"
|
||||
install -Dm755 AppRun "$pkgdir/opt/$pkgname/AppRun"
|
||||
cp -a bin resources "$pkgdir/opt/$pkgname/"
|
||||
|
||||
local icon size
|
||||
for icon in usr/share/icons/hicolor/*/apps/BambuStudio.png; do
|
||||
size="${icon#usr/share/icons/hicolor/}"
|
||||
install -Dm644 "$icon" "$pkgdir/usr/share/icons/hicolor/$size"
|
||||
done
|
||||
|
||||
install -Dm755 "$srcdir/bambu-studio" "$pkgdir/usr/bin/bambu-studio"
|
||||
install -Dm644 "$srcdir/BambuStudio.desktop" \
|
||||
"$pkgdir/usr/share/applications/BambuStudio.desktop"
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
exec "/opt/bambustudio-bin/AppRun" "$@"
|
||||
@@ -4,7 +4,7 @@
|
||||
# Automation repository: https://github.com/fabifont/claude-code-aur
|
||||
|
||||
pkgname=claude-code
|
||||
pkgver=2.1.273
|
||||
pkgver=2.1.278
|
||||
pkgrel=1
|
||||
pkgdesc="An agentic coding tool that lives in your terminal"
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -29,8 +29,8 @@ source_x86_64=("claude-${pkgver}-x86_64::https://downloads.claude.ai/claude-code
|
||||
source_aarch64=("claude-${pkgver}-aarch64::https://downloads.claude.ai/claude-code-releases/${pkgver}/linux-arm64/claude")
|
||||
|
||||
sha256sums=('SKIP')
|
||||
sha256sums_x86_64=('6c752e2cc7c110c9df15f26d8d134d438c5ae95dbd610efc1a308bf7f9c5f6c1')
|
||||
sha256sums_aarch64=('103cfab4d6ae898b6af692336fb662ffcc607075cc6408892bd350b3f549ebee')
|
||||
sha256sums_x86_64=('5c4735937844e84f8a93306e841a5b0e12252909b07870f789b190468da147ab')
|
||||
sha256sums_aarch64=('7de6cab134e48321148e30182c98614118e8f4666819412bead45865190b34ed')
|
||||
|
||||
package() {
|
||||
install -Dm755 "${srcdir}/claude-${pkgver}-${CARCH}" "${pkgdir}/opt/claude-code/bin/claude"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# repository's package index.
|
||||
|
||||
pkgname=claude-desktop
|
||||
pkgver=2.110.0
|
||||
pkgver=2.2553.1
|
||||
pkgrel=1
|
||||
pkgdesc="Official Claude desktop app with Claude Code"
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -63,8 +63,8 @@ source_x86_64=("${_deb_x86_64}::${_pool}/${_deb_x86_64}")
|
||||
source_aarch64=("${_deb_aarch64}::${_pool}/${_deb_aarch64}")
|
||||
noextract=("${_deb_x86_64}" "${_deb_aarch64}")
|
||||
sha256sums=('edfdbc63b65891ef7c481b07086c7e630fc102c042b6ed65331a52fcaf72b14a')
|
||||
sha256sums_x86_64=('f44cb8b52f6e9171ac2e67cbcc8070c4974a2f0a9b9f141b430b32b4ff541109')
|
||||
sha256sums_aarch64=('de9f24034f33dcadc53bedee92da6604e2c9268497ebff5447fedc092c884e71')
|
||||
sha256sums_x86_64=('6700fdd84e77a6b8c93912c2f69eb5d1e40fa99bcd9d37f438f809ef2a6fe6f8')
|
||||
sha256sums_aarch64=('0003a6f9605a210f03c38670d62cd59c71153c2702aa4427e4cabe2e2e5f3390')
|
||||
|
||||
package() {
|
||||
cd "${srcdir}"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Maintainer: caarlos0 <carlos@charm.sh>
|
||||
|
||||
pkgname='crush-bin'
|
||||
pkgver=0.95.0
|
||||
pkgver=0.96.0
|
||||
pkgrel=1
|
||||
pkgdesc='A powerful terminal-based AI assistant for developers, providing intelligent coding assistance directly in your terminal.'
|
||||
url='https://charm.sh/crush'
|
||||
@@ -13,16 +13,16 @@ provides=('crush')
|
||||
conflicts=('crush')
|
||||
|
||||
source_aarch64=("${pkgname}_${pkgver}_aarch64.tar.gz::https://github.com/charmbracelet/crush/releases/download/v${pkgver}/crush_${pkgver}_Linux_arm64.tar.gz")
|
||||
sha256sums_aarch64=('b42291307abe5572afb972fba9b8780f63a2058f37fb0dc61ab4c7b435314a8a')
|
||||
sha256sums_aarch64=('667062a39d499506b0fe151148f8d7a1c5cb5722902080d44bb3dd2ddafbf5c1')
|
||||
|
||||
source_armv7h=("${pkgname}_${pkgver}_armv7h.tar.gz::https://github.com/charmbracelet/crush/releases/download/v${pkgver}/crush_${pkgver}_Linux_armv7.tar.gz")
|
||||
sha256sums_armv7h=('756363804b6475ab6bf811f175a93766f47372beddb6e4a7b6e365ecba3f90ae')
|
||||
sha256sums_armv7h=('1de4c1ccb237743e4debb8c302df612fcef5c9b3b5378f5b65c8c6f8bc15cbfa')
|
||||
|
||||
source_i686=("${pkgname}_${pkgver}_i686.tar.gz::https://github.com/charmbracelet/crush/releases/download/v${pkgver}/crush_${pkgver}_Linux_i386.tar.gz")
|
||||
sha256sums_i686=('ce7b0dec1f1d9aa5a6e339f04e835bc6b3a335caf816dcb6c83a2f808d9fcd3b')
|
||||
sha256sums_i686=('4ec66431565de5721afb7afdd99e45ff6bc9c7e667bd18d9696ea7c5622e158d')
|
||||
|
||||
source_x86_64=("${pkgname}_${pkgver}_x86_64.tar.gz::https://github.com/charmbracelet/crush/releases/download/v${pkgver}/crush_${pkgver}_Linux_x86_64.tar.gz")
|
||||
sha256sums_x86_64=('edef832ff1fc03e420a0410b9653547feb816bda7e0458589434ea4164210f5e')
|
||||
sha256sums_x86_64=('5b33303a404acacf761c027e9fa9e69d4d2dd050c2690abe40877c49574b7475')
|
||||
|
||||
package() {
|
||||
case "$CARCH" in
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# binary to point at pm.sh, a stand-in that declines and names pacman instead.
|
||||
|
||||
pkgname=cua-driver-bin
|
||||
pkgver=0.28.1
|
||||
pkgver=0.28.2
|
||||
pkgrel=1
|
||||
pkgdesc="Computer-use driver for native GUI apps: accessibility-tree snapshots and input injection"
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -46,8 +46,8 @@ source_x86_64=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v$
|
||||
source_aarch64=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/cua-driver-rs-${pkgver}-linux-arm64.tar.gz")
|
||||
sha256sums=('c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9'
|
||||
'c76e251c3ed424200eac52bec35ba534336307fabd83a175ab0b47e2084ab0d8')
|
||||
sha256sums_x86_64=('a068b6e477893b77ced74bceccf7db7483cf140e8d54150ce5849b6252b90bcf')
|
||||
sha256sums_aarch64=('a863951ef0699fd25091adb87bd114d69709b887fdfc059e795aca49ef8ac19c')
|
||||
sha256sums_x86_64=('8f3e5b669e2bcd98d0eecc64f40640aac77f358b6332a06abc6ee79991620f7d')
|
||||
sha256sums_aarch64=('cadd7e6b757c3ce50f2b5f6e273c154ea48450fb5fcaff744209b382915eddf5')
|
||||
|
||||
case "${CARCH}" in
|
||||
x86_64) _platform="linux-x86_64" ;;
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
# shellcheck shell=bash disable=SC2034,SC2154
|
||||
pkgname=cua-hyprland-plugin
|
||||
pkgver=0.26.1
|
||||
pkgrel=5
|
||||
pkgdesc='Cua input candidate for reviewed profile omarchy-hyprland-0562r3-remaps'
|
||||
pkgrel=6
|
||||
pkgdesc='Cua input candidate for reviewed profile omarchy-hypr0562r3-aq0151-remaps'
|
||||
arch=('x86_64')
|
||||
url='https://github.com/trycua/cua'
|
||||
license=('MIT')
|
||||
depends=('hyprland=0.56.2-3' 'aquamarine=0.15.0-2' 'glibc=2.44+r24+g16be1518495f-1' 'hyprcursor=0.1.13-7' 'hyprgraphics=0.5.1-4' 'hyprlang=0.6.8-5' 'hyprutils=0.14.2-1' 'libgcc=16.2.1+r23+gd564253eb6c8-1' 'libstdc++=16.2.1+r23+gd564253eb6c8-1' 'libxkbcommon=1.13.2-1' 'wayland=1.26.0-1' 'python>=3.11' 'binutils')
|
||||
depends=('hyprland=0.56.2-3' 'aquamarine=0.15.1-1' 'glibc=2.44+r24+g16be1518495f-1' 'hyprcursor=0.1.13-7' 'hyprgraphics=0.5.1-4' 'hyprlang=0.6.8-5' 'hyprutils=0.14.2-1' 'libgcc=16.2.1+r23+gd564253eb6c8-1' 'libstdc++=16.2.1+r23+gd564253eb6c8-1' 'libxkbcommon=1.13.2-1' 'wayland=1.26.0-1' 'python>=3.11' 'binutils')
|
||||
makedepends=('cmake>=3.30' 'ninja' 'pkgconf' 'gcc' 'patch')
|
||||
options=('!strip' '!debug' '!lto')
|
||||
_stem='cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
|
||||
_archive_sha256='47bca9e018f32f4fcfe683f91c7475c60368f3b65d318cc35c1f2de88a4ee9ab'
|
||||
_kit_sha256='089f447e11cacd8c2d3d6cd56528776417c51d353b9677c47c42bba1ef79c9f9'
|
||||
_profile_sha256='fc3034649af98f7f81178ef575660143c249664b9ff5d0e1ccaf79d7580df17b'
|
||||
_kit_sha256='819779b93655d603d9ebb0d33ea052326c3374674a1d473886106af25e0fffdd'
|
||||
_profile_sha256='a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e'
|
||||
_verifier_sha256='480f649cbd35a0ddc7f49dc0a3a44785402c9e0ec9653b0f8ea4965d52d7f900'
|
||||
_cxx="${CUA_RELEASE_CXX:-/usr/bin/g++}"
|
||||
_download_name='cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7-profile-omarchy-stable-20260910-kit-1.1.0-5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a-67f89ceb47edd973aa748820eadd02ddbfb3d3e4.tar.gz'
|
||||
@@ -24,7 +24,7 @@ source=('https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0
|
||||
'PROFILE.json')
|
||||
noextract=("$_download_name")
|
||||
sha256sums=('a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520'
|
||||
'fc3034649af98f7f81178ef575660143c249664b9ff5d0e1ccaf79d7580df17b')
|
||||
'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e')
|
||||
|
||||
# Downstream inputs are also checked explicitly when makepkg integrity is skipped.
|
||||
declare -gA _downstream_sha256=(
|
||||
@@ -71,33 +71,34 @@ with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as contents:
|
||||
require(digest(content) == expected[member.name], 'outer kit member checksum mismatch')
|
||||
payload[member.name] = content
|
||||
require(payload.keys() == expected.keys(), 'outer kit inventory mismatch')
|
||||
# Arch's -3 package has the same compositor and all 498 headers/pkg-config
|
||||
# files as -2. Derive a version-only profile with the original source/tooling
|
||||
# and byte checks intact; record its own profile and kit provenance digests.
|
||||
# Derive the reviewed Hyprland -3/Aquamarine 0.15.1 profile while preserving
|
||||
# upstream source/tooling and compiler, compositor, header and runtime hashes.
|
||||
profile_data = Path(profile_path).read_bytes()
|
||||
require(digest(profile_data) == 'fc3034649af98f7f81178ef575660143c249664b9ff5d0e1ccaf79d7580df17b',
|
||||
require(digest(profile_data) == 'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e',
|
||||
'local profile checksum mismatch')
|
||||
profile = json.loads(payload['PROFILE.json'])
|
||||
profile.update(profile_id='omarchy-hyprland-0562r3-remaps', package_release=5)
|
||||
profile.update(profile_id='omarchy-hypr0562r3-aq0151-remaps', package_release=6)
|
||||
profile['hyprland']['package_version'] = '0.56.2-3'
|
||||
require(json.loads(profile_data) == profile, 'local profile changes more than the reviewed package revision')
|
||||
profile['runtime']['packages']['aquamarine'] = '0.15.1-1'
|
||||
require(json.loads(profile_data) == profile, 'local profile changes more than the reviewed package versions')
|
||||
payload['PROFILE.json'] = profile_data
|
||||
provenance = json.loads(payload['KIT-PROVENANCE.json'])
|
||||
provenance['profile_sha256'] = digest(profile_data)
|
||||
payload['KIT-PROVENANCE.json'] = (json.dumps(provenance, sort_keys=True, indent=2) + '\n').encode()
|
||||
recipe = payload['PKGBUILD'].decode()
|
||||
for old, new in [('pkgrel=2\n', 'pkgrel=5\n'), ('omarchy-stable-20260910', profile['profile_id']),
|
||||
for old, new in [('pkgrel=2\n', 'pkgrel=6\n'), ('omarchy-stable-20260910', profile['profile_id']),
|
||||
('hyprland=0.56.2-2', 'hyprland=0.56.2-3'),
|
||||
('aquamarine=0.15.0-2', 'aquamarine=0.15.1-1'),
|
||||
('5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a', digest(profile_data)),
|
||||
('7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997', digest(payload['KIT-PROVENANCE.json']))]:
|
||||
recipe = recipe.replace(old, new)
|
||||
payload['PKGBUILD'] = recipe.encode()
|
||||
payload['SHA256SUMS'] = ''.join(f'{digest(body)} {name}\n' for name, body in sorted(payload.items())
|
||||
if name != 'SHA256SUMS').encode()
|
||||
expected.update({'PROFILE.json': 'fc3034649af98f7f81178ef575660143c249664b9ff5d0e1ccaf79d7580df17b',
|
||||
'KIT-PROVENANCE.json': '089f447e11cacd8c2d3d6cd56528776417c51d353b9677c47c42bba1ef79c9f9',
|
||||
'PKGBUILD': '0cbf2cd34c3c5038a5ed51e6bf84acd81844e4c2bb08ad7203959201bba61da9',
|
||||
'SHA256SUMS': 'd01b9e0be4c5bcf84cc2ecef9f11f44cedfc1ca5b31afbfcf52aa2efbd636a09'})
|
||||
expected.update({'PROFILE.json': 'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e',
|
||||
'KIT-PROVENANCE.json': '819779b93655d603d9ebb0d33ea052326c3374674a1d473886106af25e0fffdd',
|
||||
'PKGBUILD': 'c3e4149eba3f7def10ef700b30b9d0abcea994e3dd32fb169014874a0b75687c',
|
||||
'SHA256SUMS': 'd9057a9534f7a820ee04cbf5d60db567c5072fa96d1f71030a6a85b4bb7ce881'})
|
||||
for name, content in payload.items():
|
||||
require(digest(content) == expected[name], 'derived kit checksum mismatch: ' + name)
|
||||
require(srcdir.is_dir() and not srcdir.is_symlink(), 'srcdir must be a real directory')
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
"sha256": "da8fcacf347bcbed83edc40108c6e2298da095e22246bd764e9bb382786cebb2"
|
||||
},
|
||||
"kit_version": "1.1.0",
|
||||
"package_release": 5,
|
||||
"profile_id": "omarchy-hyprland-0562r3-remaps",
|
||||
"package_release": 6,
|
||||
"profile_id": "omarchy-hypr0562r3-aq0151-remaps",
|
||||
"runtime": {
|
||||
"basename": "libstdc++.so.6.0.36",
|
||||
"packages": {
|
||||
"aquamarine": "0.15.0-2",
|
||||
"aquamarine": "0.15.1-1",
|
||||
"glibc": "2.44+r24+g16be1518495f-1",
|
||||
"hyprcursor": "0.1.13-7",
|
||||
"hyprgraphics": "0.5.1-4",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Optional Cua Hyprland plugin
|
||||
|
||||
This package targets **Omarchy stable x86_64**, with Inkscape `1.4.4-6` and two independent background-input lanes. Package release `5` includes the Omarchy patch for independent agent keymaps, operation-specific foreground checks, and compatible Num Lock state; the upstream native qualification below covers the unpatched source, not this change. Cua's native qualification is recorded in [the kit's qualification record](https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0-omarchy-stable-20260910/QUALIFICATION.md) and [Cua #3698](https://github.com/trycua/cua/pull/3698). Omabot replay and Omarchy's merge decision are recorded in [omarchy-pkgs #346](https://github.com/omacom/omarchy-pkgs/pull/346). Scheduling the recipe does not expand the qualified stable target.
|
||||
This package targets **Omarchy x86_64**, with Inkscape `1.4.4-6` and two independent background-input lanes. Release `6` is an edge candidate for Aquamarine `0.15.1-1`; it retains the keyboard-remap patch introduced in release `5`, which includes the Omarchy patch for independent agent keymaps, operation-specific foreground checks, and compatible Num Lock state; the upstream native qualification below covers the unpatched source, not this change. Cua's native qualification is recorded in [the kit's qualification record](https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0-omarchy-stable-20260910/QUALIFICATION.md) and [Cua #3698](https://github.com/trycua/cua/pull/3698). Omabot replay and Omarchy's merge decision are recorded in [omarchy-pkgs #346](https://github.com/omacom/omarchy-pkgs/pull/346). Scheduling the recipe does not expand the qualified stable target.
|
||||
|
||||
The plugin is optional. Cua Driver works independently, and installation does not load the plugin or enable input. The package follows the normal edge-to-RC-to-stable promotion path instead of the fast release ring. Its PKGBUILD limits builds to x86_64; only stable x86_64 is a qualified target.
|
||||
The plugin is optional. Cua Driver works independently, and installation does not load the plugin or enable input. The package follows the normal edge-to-RC-to-stable promotion path instead of the fast release ring. Its PKGBUILD limits builds to x86_64. The upstream qualification covers the original stable profile; the updated Aquamarine profile needs its own Omabot validation before promotion.
|
||||
|
||||
## Source and build profile
|
||||
|
||||
@@ -12,26 +12,23 @@ It is not a repackaging of the unmodified 0.24.0 plugin.
|
||||
|
||||
The qualified upstream Driver pairing is `cua-driver-bin 0.27.0-1`, with input protocol v3. Driver 0.27.0 contains the bounded stale-geometry retry validated with the upstream module; its production plugin source is the base for the downstream patch used here. Discovery protocol v2 is separate. A newer Driver release is a changed pairing and requires affected replay before promotion.
|
||||
|
||||
Profile `omarchy-hyprland-0562r3-remaps`, kit tooling `1.1.0`, and package release `5` pin:
|
||||
Profile `omarchy-hypr0562r3-aq0151-remaps`, kit tooling `1.1.0`, and package release `6` pin:
|
||||
|
||||
- Hyprland `0.56.2-3`, headers `0.56.2`, and measured executable/header hashes.
|
||||
- GCC `16.2.1 20260810`, including compiler bytes and emitted ELF identity.
|
||||
- Shared runtime `libstdc++.so.6.0.36`, its bytes, and exact ABI package versions.
|
||||
- Shared runtime `libstdc++.so.6.0.36`, its bytes, and exact ABI package versions, including Aquamarine `0.15.1-1`.
|
||||
|
||||
This profile derives from Cua's `omarchy-stable-20260910` profile. Arch's
|
||||
Hyprland `-3` package splits out `hyprpm` and changes package dependencies;
|
||||
its compositor executable and all 498 header/pkg-config files are byte-identical
|
||||
to `-2`. Both executables have SHA-256
|
||||
`da8fcacf347bcbed83edc40108c6e2298da095e22246bd764e9bb382786cebb2`.
|
||||
The checked-in `PROFILE.json` changes only the profile name, package release,
|
||||
and exact Hyprland package version. Compiler, runtime, upstream source, executable,
|
||||
and header identities remain unchanged; the separately recorded patch changes the build source. The download wrapper verifies the
|
||||
The checked-in `PROFILE.json` changes only the profile name, package release, and exact Hyprland and Aquamarine package versions. Compiler, libstdc++ runtime, upstream source, compositor executable, and header identities remain unchanged; the separately recorded patch changes the build source. The download wrapper verifies the
|
||||
original kit before deriving the updated profile, recipe, and provenance,
|
||||
then verifies every derived member against its recorded digest.
|
||||
|
||||
The native qualification below was recorded with package release `2` and
|
||||
Hyprland `-2`. The downstream keymap change needs its own application and Driver replay before promotion. The `-3` dependency must reach a destination channel before
|
||||
this artifact can be installed there; publication still follows edge → RC → stable.
|
||||
Hyprland `-2`. The downstream keymap change and Aquamarine update need their own application and Driver replay before promotion. Hyprland `0.56.2-3` and Aquamarine `0.15.1-1` must both reach a destination channel before this artifact can be installed there; publication still follows edge → RC → stable.
|
||||
|
||||
The generated `PKGBUILD` identifies the immutable kit download, outer checksum,
|
||||
and member checksums. The kit records the full source and tooling revisions,
|
||||
@@ -48,6 +45,12 @@ Production input is built in; experimental signed input and tracing are off.
|
||||
|
||||
The pristine upstream archive, manifest, and verifier remain unchanged. `independent-keymaps.patch` is applied to a separate source tree, and `DOWNSTREAM-PROVENANCE.json` pins the patch and every resulting source file. Build, check, and package revalidate both trees, including when makepkg integrity checks are skipped. `BUILD-PROVENANCE.json` records the upstream base under `source`, the applied change under `downstream`, and the final module digest; the downstream manifest and patch are installed beside it. This preserves the existing compiler, headers, runtime, and consumer checks without representing the modified module as an unmodified upstream build.
|
||||
|
||||
## Aquamarine dependency refresh
|
||||
|
||||
Release `5` required Aquamarine `0.15.0-2`. When the edge mirror moved to `0.15.1-1`, pacman could no longer resolve that dependency, even after a full database refresh. Release `6` derives a new profile from the same verified upstream kit and pins `0.15.1-1` in both the package dependencies and the installed compatibility verifier. Source, patch, compiler, compositor, headers, and libstdc++ hashes remain pinned; the original upstream qualification does not establish compatibility with the changed Aquamarine package.
|
||||
|
||||
A package release bump alone cannot repair future dependency drift: the checked-in profile and derived kit checksums must agree with the new environment, and affected native checks must pass before publication. Do not remove exact dependencies or selectively downgrade a library to bypass a mismatch.
|
||||
|
||||
## Keyboard behavior
|
||||
|
||||
Each background lane owns a canonical US keymap and independent modifier state. The physical keyboard keeps its layout, Compose key, and remaps. No installation or activation step edits `input:kb_*`. Existing Driver keycodes are interpreted by the agent keyboard, so this does not add Unicode, IME, or new Driver text routes.
|
||||
@@ -142,7 +145,7 @@ kit-provenance digest:
|
||||
```sh
|
||||
python3 /usr/share/cua-hyprland-plugin/profile_verify.py \
|
||||
--kit /usr/share/cua-hyprland-plugin \
|
||||
--kit-sha256 089f447e11cacd8c2d3d6cd56528776417c51d353b9677c47c42bba1ef79c9f9 \
|
||||
--kit-sha256 819779b93655d603d9ebb0d33ea052326c3374674a1d473886106af25e0fffdd \
|
||||
--consumer /usr/lib/cua/hyprland/cua-hyprland-plugin.so
|
||||
```
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Gunther Schulz <dev@guntherschulz.de>
|
||||
|
||||
pkgname=cursor-bin
|
||||
pkgver=3.20.21
|
||||
pkgver=3.21.16
|
||||
pkgrel=2
|
||||
pkgdesc='AI-first coding environment'
|
||||
arch=('x86_64')
|
||||
@@ -12,11 +12,11 @@ _electron=electron42
|
||||
depends=(xdg-utils ripgrep $_electron nodejs
|
||||
'gcc-libs' 'hicolor-icon-theme' 'libxkbfile')
|
||||
options=(!strip !debug) # Don't break ext of VSCode
|
||||
_commit=f09fca384ceca23f7bf21f9c23655b162641d747
|
||||
_commit=8ae78e8eee1e63479c7e0504b664bc0a80c6800f
|
||||
source=("https://downloads.cursor.com/production/${_commit}/linux/x64/deb/amd64/deb/cursor_${pkgver}_amd64.deb"
|
||||
"https://gitlab.archlinux.org/archlinux/packaging/packages/code/-/raw/main/code."{sh,mjs}
|
||||
rg.sh)
|
||||
sha512sums=('8329138d207309d16410f1cb58da18eea1a034a35f2bdd022ef9b373bb8f1b3d80e489e65256b7283c40e10da77962d158bfa3a64e742337a942633810d80dbe' '937299c6cb6be2f8d25f7dbc95cf77423875c5f8353b8bd6cd7cc8e5603cbf8405b14dbf8bd615db2e3b36ed680fc8e1909410815f7f8587b7267a699e00ab37' '793f9ff6306e3992ac89802d98110cba288ea1181a901467333293b7d76182ef9792c2a39ff49d9347a18a174b1f42bc58862091dff583f4146c2704eea28033' 'e79fe7659f59d1ae02fc68816399bfd31587315df6cdb6ccf1d0ca76f7cdc692c2a42b30591c0091147bd97ef14b1c7745dc26bd7cb3ea6bba45698e5044fa2a')
|
||||
sha512sums=('032c86a5d51f154ce36b1a0bf34aa06b2d117666b4372a787ea3117fc0b2b1686e952c721388f2eaf7787f2e0581378c98608048126f7470df2e85e9dbd75ca4' '937299c6cb6be2f8d25f7dbc95cf77423875c5f8353b8bd6cd7cc8e5603cbf8405b14dbf8bd615db2e3b36ed680fc8e1909410815f7f8587b7267a699e00ab37' '793f9ff6306e3992ac89802d98110cba288ea1181a901467333293b7d76182ef9792c2a39ff49d9347a18a174b1f42bc58862091dff583f4146c2704eea28033' 'e79fe7659f59d1ae02fc68816399bfd31587315df6cdb6ccf1d0ca76f7cdc692c2a42b30591c0091147bd97ef14b1c7745dc26bd7cb3ea6bba45698e5044fa2a')
|
||||
noextract=(cursor_${pkgver}_amd64.deb) # avoid double tarball
|
||||
_app=usr/share/cursor/resources/app
|
||||
package() {
|
||||
@@ -24,6 +24,9 @@ package() {
|
||||
bsdtar -xOf ${noextract[0]} data.tar.xz | tar -xJf - -C "$pkgdir" \
|
||||
--exclude 'usr/share/cursor/[^r]*' --exclude 'usr/share/cursor/*.pak'
|
||||
cd "$pkgdir"
|
||||
# Disable Cursor's bundled updater; Omarchy manages updates via pacman (#238).
|
||||
sed -i '/^[[:space:]]*"\(backupUpdateUrl\|updateUrl\)":/d' \
|
||||
"${_app}/product.json"
|
||||
mv usr/share/zsh/{vendor-completions,site-functions}
|
||||
ln -sf /usr/bin/node ${_app}/resources/helpers/node
|
||||
install -Dm755 "${srcdir}/rg.sh" ${_app}/node_modules/@vscode/ripgrep/bin/rg
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Ismet Togay <ismet.togay at gmail dot com>
|
||||
# Contributor: Christopher Cooper <christopher@cg505.com>
|
||||
pkgname=cursor-cli
|
||||
pkgver=2026.09.10.1.fd3934a
|
||||
pkgver=2026.09.18.1.9a7762b
|
||||
# Upstream is YYYY.MM.DD-<hash>. pkgver cannot contain hyphens, and hashes are
|
||||
# not monotonically ordered, so pkgver is YYYY.MM.DD.<n>.<hash>: n resets to 1
|
||||
# on a new date and increments when the same date gets a new hash.
|
||||
@@ -25,8 +25,8 @@ source_x86_64=("cursor-cli-${_upstream_ver}-x86_64.tar.gz::https://downloads.cur
|
||||
source_aarch64=("cursor-cli-${_upstream_ver}-aarch64.tar.gz::https://downloads.cursor.com/lab/${_upstream_ver}/linux/arm64/agent-cli-package.tar.gz")
|
||||
b2sums=('d241ee9895bdb1c17514438fde8528222a8f2326568bd7a033d7a1b11432ce6b4575ff1a50625764bfe6bc6f8a9dc060f7439c3be7e95f8fd02912cdd37a011d'
|
||||
'1928e04c713e13911ea607f84c3e4a2fed1f76af9795503811078f43d2b53c753e28b2233e553fc17e766831800fb0dbc272aad2a80b387f95ba6071d7d4116a')
|
||||
b2sums_x86_64=('121c0128fd630565c7000b86ae53bf76e73fd72c1ab8ba2509fae7739b1c7f4bed0587a82137340303ac4704f3344cf63a10eab0e8bea262c8e48bbb21bcb742')
|
||||
b2sums_aarch64=('bfc0f540190214396df3cbb93c411ab8055677bc1dd0b0e76d1b914d6c6d90af12519434227ba8b38a38249f1bfe0a8848f47e16dc048b4fa005d366815307be')
|
||||
b2sums_x86_64=('3fccee6929df1042d03461895e56c222a996d3ae9e4f9c61dcc5e6ab7b1d075d3265c21a44f48dd94de0dcde4f8012cc39bfbf323e2bb0c6106cac79885c35ae')
|
||||
b2sums_aarch64=('3d3bb0a3cb7e2409acf4925f207eaa4e3f41782c3c947e2834b69664b116b972da0b67eea17147fc524ea248af9919494570adc7c48d12c44f12deca17ba2c28')
|
||||
|
||||
prepare() {
|
||||
# Block cursor-agent auto-updates by making its versions directory
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pkgname=dell-xps-touchpad-haptics
|
||||
pkgver=1.0.0
|
||||
pkgrel=3
|
||||
pkgrel=4
|
||||
pkgdesc="Synaptics haptic touchpad presets for Dell XPS on Omarchy"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/omacom-io/omarchy-pkgs"
|
||||
|
||||
@@ -3,6 +3,7 @@ _default_level="high"
|
||||
_env_path="/etc/dell-xps-touchpad-haptics.env"
|
||||
_legacy_env_path="/etc/omarchy-dell-haptic-touchpad.env"
|
||||
_legacy_override_dir="/etc/systemd/system/dell-xps-haptic-touchpad.service.d"
|
||||
_runuser_path="/usr/bin/runuser"
|
||||
|
||||
_existing_home() {
|
||||
local line value
|
||||
@@ -124,18 +125,13 @@ _ensure_user_config() {
|
||||
local config_dir="$home/.config/omarchy"
|
||||
local config_path="$config_dir/dell-haptic.conf"
|
||||
|
||||
if [[ ! -f $config_path ]] && ! env HOME="$home" USER="$user" LOGNAME="$user" \
|
||||
if [[ ! -f $config_path ]] && ! "$_runuser_path" --user "$user" -- \
|
||||
/usr/bin/env HOME="$home" USER="$user" LOGNAME="$user" \
|
||||
/usr/bin/dell-xps-touchpad-haptics set "$_default_level"; then
|
||||
echo ":: Failed to create ${config_path} for user '$user'." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -f $config_path ]]; then
|
||||
chown "$user:$user" "$home/.config" 2>/dev/null || true
|
||||
chown "$user:$user" "$config_dir" 2>/dev/null || true
|
||||
chown "$user:$user" "$config_path" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# elsewhen
|
||||
|
||||
Installs the Elsewhen world clock plugin from the `v{pkgver}` GitHub tag archive into `/usr/share/omarchy/shell/plugins/omacom.elsewhen/` (the directory name is the plugin id the shell scans for, not the package name), plus `LICENSE` under `/usr/share/licenses/elsewhen/` and the upstream `README.md` under `/usr/share/doc/elsewhen/`. The shell scans this directory alongside its bundled plugins.
|
||||
|
||||
`package()` copies an explicit allow-list (`manifest.json`, every `*.qml` and `*.js`, `cities.json`, `world.json`, `worldclock-data.py`), so `tests/`, `.github/` and `.gitignore` never ship, and it fails the build if `manifest.json` is missing, does not declare `omacom.elsewhen`, or does not name a present `Panel.qml` as the entry point. An upstream release that adds a runtime file outside those patterns needs the allow-list extended here; the sync only moves versions and checksums. Every file is 0644: `Panel.qml` runs the script as `python3 <plugin dir>/worldclock-data.py`, so it needs no execute bit. No install hook: Omarchy restarts the shell after `omarchy update`, and nothing here may write into a user home. The script's only writes go to `$XDG_CACHE_HOME/omacom-elsewhen/`, which it creates itself at runtime.
|
||||
|
||||
Dependencies, cited as `file: tool` in the upstream tree:
|
||||
|
||||
- `omarchy`: `ArcText.qml`, `Chip.qml`, `EarthRow.qml`, `Globe.qml`, `MiniGlobe.qml`, `MoonDot.qml`, `Panel.qml: import qs.Commons`; `EarthRow.qml`, `Globe.qml`, `Panel.qml: import qs.Ui`. Owns `/usr/share/omarchy` and the shell plugin directory.
|
||||
- `quickshell`: `Globe.qml`, `Panel.qml: import Quickshell`; `Globe.qml`, `MiniGlobe.qml`, `Panel.qml: import Quickshell.Io` (`Process`, `FileView`, `StdioCollector`).
|
||||
- `python`: `Panel.qml: python3 <plugin dir>/worldclock-data.py` (the facts process). `worldclock-data.py` imports only `json`, `os`, `sys`, `time`, `urllib`.
|
||||
- Left implicit as members of `base`, per Arch convention: `bash` (`Panel.qml`, `Globe.qml: bash -c` wraps every probe), `coreutils` (`Panel.qml`, `Globe.qml: date`, one probe per refresh), `systemd` (`Panel.qml: timedatectl show`, `timedatectl list-timezones`, each with a fallback: `/etc/localtime` for the home zone and `find /usr/share/zoneinfo` for the catalog), `sed` and `grep` (`Panel.qml`: the symlink target of `/etc/localtime` and the zoneinfo catalog filter), `findutils` and `tzdata` (that fallback; `worldclock-data.py: /usr/share/zoneinfo/zone1970.tab`). `omarchy` cannot run without any of them either.
|
||||
- Not a dependency: `iso-codes`. Only `tests/currency_check.py` reads `/usr/share/iso-codes/json`, to validate the currency table before a release; the runtime never touches it.
|
||||
|
||||
Release tracking: `bin/sync-upstream` follows `omacom/elsewhen` through the `upstream.watch.github` provider, which reads the GitHub Releases feed (drafts and prereleases excluded; a tag with no published Release is not seen) and matches exactly `vX.Y.Z`, the grammar upstream's `scripts/set-version.sh` enforces. A newer release rewrites `pkgver`, resets `pkgrel` to 1, fetches `archive/refs/tags/v{pkgver}.tar.gz` again and rewrites `sha256sums` from the download. The Release's `published_at` is what lets `min_release_age: 24h` hold a fresh release for a day; `release_ring: fast` builds it straight to rc and stable as well as edge.
|
||||
|
||||
The watch only moves on a version increase, so the first release's digest is filled in by hand (`curl -fsSL <archive url> | sha256sum`), which is why the recipe carries a placeholder until the `v0.1.0` tag exists. Until upstream has published at least one Release, the watch finds nothing and fails the scheduled `sync-upstream` run for every package in the batch, so this recipe stays a draft until then.
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"source": "local",
|
||||
"release_ring": "fast",
|
||||
"min_release_age": "24h",
|
||||
"upstream": {
|
||||
"watch": {
|
||||
"github": "omacom/elsewhen",
|
||||
"pattern": "v(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
# Maintainer: Spencer Bull <spencer.bull@hey.com>
|
||||
|
||||
pkgname=elsewhen
|
||||
pkgver=1.0.0
|
||||
pkgrel=2
|
||||
pkgdesc='World clock plugin for the Omarchy shell'
|
||||
arch=('any')
|
||||
url='https://github.com/omacom/elsewhen'
|
||||
license=('MIT')
|
||||
|
||||
# What the plugin needs to load and run. It also shells out to bash, date
|
||||
# (coreutils) and timedatectl (systemd) and reads /usr/share/zoneinfo
|
||||
# (tzdata); those are members of the base group and stay implicit, per Arch
|
||||
# convention. The citations for each entry are in .omarchy/README.md.
|
||||
depends=(
|
||||
'omarchy'
|
||||
'python'
|
||||
'quickshell'
|
||||
)
|
||||
|
||||
options=('!debug')
|
||||
|
||||
source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz")
|
||||
sha256sums=('3124f0c0a19ebc1b158bcf04151cddd6c733ceeead88052186b6a54c46bee263')
|
||||
|
||||
package() {
|
||||
# Install alongside the bundled plugins in the shell's plugin directory.
|
||||
local plugin="$pkgdir/usr/share/omarchy/shell/plugins/omacom.elsewhen"
|
||||
cd "$srcdir/$pkgname-$pkgver" || return 1
|
||||
|
||||
# The shell loads the entry point each manifest declares. A tree without
|
||||
# either would install cleanly and never load, so fail the build instead of
|
||||
# shipping it.
|
||||
[[ -f manifest.json ]] || {
|
||||
echo "release tree is missing manifest.json" >&2
|
||||
return 1
|
||||
}
|
||||
grep -Eq '"id"[[:space:]]*:[[:space:]]*"omacom\.elsewhen"' manifest.json || {
|
||||
echo "manifest.json does not declare the plugin id omacom.elsewhen" >&2
|
||||
return 1
|
||||
}
|
||||
grep -Eq '"barWidget"[[:space:]]*:[[:space:]]*"Panel\.qml"' manifest.json || {
|
||||
echo "manifest.json does not name Panel.qml as the bar widget entry point" >&2
|
||||
return 1
|
||||
}
|
||||
[[ -f Panel.qml ]] || {
|
||||
echo "release tree is missing the entry point Panel.qml" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# An explicit allow-list of runtime files, so tests/, .github/ and the rest
|
||||
# of the repository never reach the package. Directories end up 0755 and
|
||||
# every file 0644: worldclock-data.py runs as `python3 <path>` and needs no
|
||||
# execute bit. An unmatched glob is left literal and fails install, which
|
||||
# is the right outcome for a release tree missing its QML or JS.
|
||||
local file
|
||||
for file in manifest.json cities.json world.json worldclock-data.py *.qml *.js; do
|
||||
install -Dm644 "$file" "$plugin/$file"
|
||||
done
|
||||
|
||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||
install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md"
|
||||
}
|
||||
@@ -85,6 +85,14 @@ sharelink_qml=$(tar -xOzf "$tarball" "$expected_root/ui/ShareLink.qml")
|
||||
copyfile_rs=$(tar -xOzf "$tarball" "$expected_root/src/backend/copyfile.rs")
|
||||
regfile_rs=$(tar -xOzf "$tarball" "$expected_root/src/backend/regfile.rs")
|
||||
|
||||
# Every check below pins a literal line except the O_NOFOLLOW one. That check
|
||||
# guards a property -- the copy opens its source with O_NOFOLLOW, so a symlink
|
||||
# swapped in cannot redirect the read -- and pinning the exact call expression
|
||||
# made it assert the spelling instead. v0.3.0 moved the first argument from
|
||||
# `src` to `src.at` when directory-relative opens landed, kept O_NOFOLLOW, and
|
||||
# hardened symlink handling further; the literal still refused it. Match the
|
||||
# call and the flag together so a rename cannot read as a removed fix, while
|
||||
# dropping O_NOFOLLOW still fails.
|
||||
if ! grep -Fq 'a.push("--".to_string());' <<<"$archive_rs" ||
|
||||
! grep -Fq 'let input = std::fs::canonicalize(input)' <<<"$archiveops_rs" ||
|
||||
! grep -Fq 'if op != "compress" && op != "extract"' <<<"$run_rs$archivereq_rs" ||
|
||||
@@ -92,7 +100,7 @@ if ! grep -Fq 'a.push("--".to_string());' <<<"$archive_rs" ||
|
||||
! grep -Fq 'if !sandbox::available()' <<<"$mediaprobe_rs" ||
|
||||
! grep -Fq 'if !sandbox::available()' <<<"$metareq_rs" ||
|
||||
! grep -Fq 'copyToClipboard.command = ["wl-copy", url]' <<<"$sharelink_qml" ||
|
||||
! grep -Fq 'regfile::open_if_regular(src, O_NOFOLLOW)' <<<"$copyfile_rs" ||
|
||||
! grep -Eq 'open_if_regular\(.*O_NOFOLLOW' <<<"$copyfile_rs" ||
|
||||
! grep -Fq '.custom_flags(O_NONBLOCK | extra_flags)' <<<"$regfile_rs"; then
|
||||
printf 'Release %s does not contain every required upstream security fix\n' "$best_tag" >&2
|
||||
exit 1
|
||||
|
||||
+37
-4
@@ -1,8 +1,8 @@
|
||||
# Maintainer: GM <gianmarcomorales@icloud.com>
|
||||
|
||||
pkgname=flea
|
||||
pkgver=0.2.1
|
||||
pkgrel=3
|
||||
pkgver=0.3.1
|
||||
pkgrel=2
|
||||
pkgdesc='Fast, keyboard-first file manager for Omarchy'
|
||||
arch=('x86_64' 'aarch64')
|
||||
url='https://github.com/thisisgm/flea'
|
||||
@@ -15,7 +15,10 @@ depends=(
|
||||
'glib2'
|
||||
'glibc'
|
||||
'gvfs'
|
||||
'gvfs-afc'
|
||||
'gvfs-dnssd'
|
||||
'gvfs-gphoto2'
|
||||
'gvfs-mtp'
|
||||
'gvfs-nfs'
|
||||
'gvfs-smb'
|
||||
'hicolor-icon-theme'
|
||||
@@ -28,6 +31,7 @@ depends=(
|
||||
'qt6-multimedia'
|
||||
'qt6-webengine'
|
||||
'shared-mime-info'
|
||||
'usbmuxd'
|
||||
'util-linux'
|
||||
'wl-clipboard'
|
||||
'xdg-terminal-exec'
|
||||
@@ -48,7 +52,7 @@ options=('!debug')
|
||||
source=(
|
||||
"$url/releases/download/v$pkgver/$pkgname-v$pkgver.tar.gz"
|
||||
)
|
||||
sha256sums=('75f9ac0274a09a0d55cf7d9187943983c1b78a9e443465738b3ac8af8f2a77e9')
|
||||
sha256sums=('b146ac3f5025da987eae623c4392c44ce69a6a7275a8df3ec1a84563920a4dd2')
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
@@ -60,7 +64,13 @@ build() {
|
||||
check() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
export CARGO_TARGET_DIR=target
|
||||
# Upstream's release profile uses fat LTO, whose final link runs on one
|
||||
# thread. build() keeps it for the shipped binary; the test harness is a
|
||||
# throwaway second compile, so build it in parallel in its own target
|
||||
# directory.
|
||||
export CARGO_TARGET_DIR=target-check
|
||||
export CARGO_PROFILE_RELEASE_LTO=thin
|
||||
export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=16
|
||||
|
||||
local -a test_args=()
|
||||
if ! /usr/bin/prlimit --cpu=30 --as=1073741824 \
|
||||
@@ -99,6 +109,12 @@ check() {
|
||||
# not provide. Keep executable fixtures in the remaining suites on the normal
|
||||
# temp root (/dev/shm is noexec). Note that /dev/shm does NOT buy finer
|
||||
# timestamps -- see the skip below.
|
||||
# shelfundo::tests::undo_refuses_to_walk_a_stranger_back deletes a file,
|
||||
# creates another under the same name, and expects undo to tell them
|
||||
# apart by (dev, ino, kind). ext4 hands the freed inode number straight
|
||||
# back to the next create, so on the builder's /tmp the stranger is
|
||||
# identical and undo walks it back. tmpfs allocates inode numbers from a
|
||||
# counter and never reuses one, which is what the test assumes.
|
||||
local -a filesystem_tests=(
|
||||
backend::menu_actions::tests::
|
||||
backend::menudelete::tests::
|
||||
@@ -106,6 +122,7 @@ check() {
|
||||
backend::trashbrowse::tests::
|
||||
backend::trashdelete::
|
||||
backend::trashmanifest::tests::
|
||||
shelfundo::tests::
|
||||
)
|
||||
# redo_refuses_changed_sources_and_destination_collisions writes a file and
|
||||
# then immediately asks redo to notice the edit. flea decides "changed" from
|
||||
@@ -123,6 +140,19 @@ check() {
|
||||
--skip backend::redo::tests::redo_refuses_changed_sources_and_destination_collisions
|
||||
)
|
||||
|
||||
# These three expect spawning a missing or failing program to be reported
|
||||
# as such. aarch64 builds run under QEMU user-mode emulation, where
|
||||
# glibc's posix_spawn cannot see the child's failed execve: the spawn
|
||||
# "succeeds" with exit 127, and the timing test's child never sleeps.
|
||||
# Passes natively.
|
||||
if [[ $CARCH == aarch64 ]]; then
|
||||
test_args+=(
|
||||
--skip backend::child::tests::a_child_is_noticed_when_it_exits_rather_than_at_the_next_poll_boundary
|
||||
--skip backend::child::tests::a_child_that_never_started_is_told_apart_from_one_that_ran_and_failed
|
||||
--skip backend::menu_registry::tests::unavailable_failed_and_oversized_queries_are_named_errors
|
||||
)
|
||||
fi
|
||||
|
||||
local test_tmp test_status=0 suite
|
||||
test_tmp=$(mktemp -d /dev/shm/flea-tests.XXXXXXXX) || return 1
|
||||
TMPDIR="$test_tmp" cargo test --frozen --release -- \
|
||||
@@ -158,6 +188,9 @@ package() {
|
||||
|
||||
install -Dm644 ui/qmldir ui/*.qml -t "$pkgdir/usr/share/flea/ui"
|
||||
install -Dm644 ui/js/*.js -t "$pkgdir/usr/share/flea/ui/js"
|
||||
# Flea's Shelf setting installs this plugin into the user's plugin directory.
|
||||
install -Dm644 shelf/manifest.json shelf/README.md shelf/*.qml shelf/*.js \
|
||||
-t "$pkgdir/usr/share/flea/shelf"
|
||||
ln -s /usr/share/omarchy/shell/Commons "$pkgdir/usr/share/flea/ui/Commons"
|
||||
ln -s /usr/share/omarchy/shell/Ui "$pkgdir/usr/share/flea/ui/Ui"
|
||||
}
|
||||
@@ -6,7 +6,7 @@ _npmmodule=@github/copilot
|
||||
pkgname=github-copilot-cli
|
||||
_pkgexec=copilot
|
||||
|
||||
pkgver=1.0.85
|
||||
pkgver=1.0.86
|
||||
pkgrel=1
|
||||
|
||||
pkgdesc="GitHub Copilot CLI brings the power of Copilot coding agent directly to your terminal."
|
||||
@@ -31,8 +31,8 @@ source=("https://registry.npmjs.org/${_npmmodule}/-/copilot-${pkgver}.tgz"
|
||||
noextract=("copilot-${pkgver}.tgz")
|
||||
|
||||
sha256sums=(
|
||||
'd26e3c15310bdcdcc910ed223285bed8d68aaebce0d344f97224b5cfdaeeee36'
|
||||
'1b1a8fbd5562df73684b6e94865837ceffd6609d61822c39e6c8fcbd32d8ac41'
|
||||
'4c6433345f08199e96dcf8db1c3e46a337dfab96cea32132d6127ffcd63a6200'
|
||||
'b94d2aab574cf3e0c8d950e72430186cdd918261a1376146de971fa90ba0a672'
|
||||
)
|
||||
|
||||
# Document: https://wiki.archlinux.org/title/Node.js_package_guidelines
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"source": "local"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# Maintainer: David Heinemeier Hansson <david@hey.com>
|
||||
|
||||
pkgname=gliff
|
||||
pkgver=0.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Hyprland remote desktop over SSH (Vulkan Video, 4:4:4)"
|
||||
arch=('x86_64')
|
||||
url="https://github.com/kevinmcconnell/gliff"
|
||||
license=('MIT')
|
||||
depends=('gcc-libs' 'glibc' 'wayland' 'libxkbcommon' 'libdrm' 'mesa'
|
||||
'gtk4>=4.14' 'libadwaita>=1.5' 'vulkan-icd-loader' 'openssh')
|
||||
makedepends=('cargo' 'pkgconf')
|
||||
optdepends=('vulkan-radeon: Vulkan Video on AMD'
|
||||
'vulkan-intel: Vulkan Video on Intel'
|
||||
'vulkan-tools: vulkaninfo for debugging'
|
||||
'vulkan-validation-layers: driver call validation for development')
|
||||
options=('!debug')
|
||||
|
||||
# Upstream only publishes a rolling prerelease; pin its source for reproducible builds.
|
||||
_commit=2edbfba52780c7ace15dbb05ca92177f493d4bc9
|
||||
source=("$pkgname-$_commit.tar.gz::$url/archive/$_commit.tar.gz")
|
||||
sha256sums=('2d75961085a72fb8e34149de63e312a7336daa70fd6e157e30c2cd08c14eb1c7')
|
||||
|
||||
prepare() {
|
||||
cd "$pkgname-$_commit"
|
||||
|
||||
cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$_commit"
|
||||
|
||||
export CARGO_TARGET_DIR=target
|
||||
cargo build --frozen --release
|
||||
}
|
||||
|
||||
check() {
|
||||
cd "$pkgname-$_commit"
|
||||
|
||||
export CARGO_TARGET_DIR=target
|
||||
cargo test --frozen --release --workspace
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname-$_commit"
|
||||
|
||||
install -Dm755 target/release/gliff "$pkgdir/usr/bin/gliff"
|
||||
install -Dm755 target/release/gliff-server "$pkgdir/usr/bin/gliff-server"
|
||||
install -Dm755 target/release/gliff-probe "$pkgdir/usr/bin/gliff-probe"
|
||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||
install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md"
|
||||
install -Dm644 docs/hardware-quirks.md "$pkgdir/usr/share/doc/$pkgname/hardware-quirks.md"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: David Heinemeier Hansson <david@hey.com>
|
||||
|
||||
pkgname=herdr
|
||||
pkgver=0.9.0
|
||||
pkgver=0.9.1
|
||||
pkgrel=1
|
||||
pkgdesc="Herdr terminal workspace manager for AI coding agents"
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -13,13 +13,13 @@ replaces=('omarchy-herdr')
|
||||
conflicts=('omarchy-herdr')
|
||||
options=('!debug' '!lto')
|
||||
|
||||
_zigver=0.15.2
|
||||
_zigver=0.16.0
|
||||
source=("herdr-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz")
|
||||
source_x86_64=("zig-x86_64-linux-$_zigver.tar.xz::https://ziglang.org/download/$_zigver/zig-x86_64-linux-$_zigver.tar.xz")
|
||||
source_aarch64=("zig-aarch64-linux-$_zigver.tar.xz::https://ziglang.org/download/$_zigver/zig-aarch64-linux-$_zigver.tar.xz")
|
||||
sha256sums=('1e83bff4b05834ed8281e16f1680e8f3e58375a94b2e3f2b3d021e28e293ef9a')
|
||||
sha256sums_x86_64=('02aa270f183da276e5b5920b1dac44a63f1a49e55050ebde3aecc9eb82f93239')
|
||||
sha256sums_aarch64=('958ed7d1e00d0ea76590d27666efbf7a932281b3d7ba0c6b01b0ff26498f667f')
|
||||
sha256sums=('03403d3ef80dcf2b954dd5d27eb636e6c4f5279d240b48de272b7f53e4b73093')
|
||||
sha256sums_x86_64=('70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00')
|
||||
sha256sums_aarch64=('ea4b09bfb22ec6f6c6ceac57ab63efb6b46e17ab08d21f69f3a48b38e1534f17')
|
||||
|
||||
prepare() {
|
||||
cd "herdr-$pkgver"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Maintainer: CommandMC <kate@commandmc.de>
|
||||
|
||||
pkgname=heroic-games-launcher-bin
|
||||
pkgver=2.22.2
|
||||
pkgver=2.22.3
|
||||
pkgrel=1
|
||||
pkgdesc="An Open source Launcher for Epic, Amazon and GOG Games"
|
||||
arch=('x86_64')
|
||||
@@ -11,7 +11,7 @@ license=('GPL-3.0-only')
|
||||
_filename=Heroic-${pkgver}-linux-x64.pacman
|
||||
source=("https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher/releases/download/v${pkgver}/${_filename}")
|
||||
noextract=("${_filename}")
|
||||
sha256sums=('4e4033ac70b8c407eaf70ce072e4e4d017200f07a3e88f7cfd4d3a597f3c09b8')
|
||||
sha256sums=('ed17ce083a71dd7e49a89218052ab475edd5a654cedf443853f6baacbb0a00e9')
|
||||
options=(!strip)
|
||||
depends=(
|
||||
which
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"source": "local"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# Maintainer: David Heinemeier Hansson <david@hey.com>
|
||||
|
||||
pkgname=hype
|
||||
pkgver=0.4.1
|
||||
pkgrel=1
|
||||
pkgdesc='Simple Markdown presentations with a visual slide editor'
|
||||
arch=('x86_64' 'aarch64')
|
||||
url='https://github.com/omacom/hype'
|
||||
license=('MIT')
|
||||
install='hype.install'
|
||||
options=('!debug')
|
||||
depends=(
|
||||
'ffmpeg'
|
||||
'hicolor-icon-theme'
|
||||
'qt6-base>=6.9'
|
||||
'qt6-declarative>=6.9'
|
||||
'qt6-multimedia>=6.9'
|
||||
'qt6-imageformats'
|
||||
'qt6-svg'
|
||||
'source-highlight'
|
||||
'zlib'
|
||||
'libwebp'
|
||||
'xdg-desktop-portal'
|
||||
)
|
||||
makedepends=('gcc' 'make')
|
||||
source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz")
|
||||
sha256sums=('0724a9d18df7657b50dff21ffe3dec1c107e9191a9e9fd5ad40b56ed9d5d6f51')
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
./bin/build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
|
||||
install -Dm755 build/hype "$pkgdir/usr/bin/hype"
|
||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||
install -Dm644 pkgbuild/hype.svg "$pkgdir/usr/share/icons/hicolor/scalable/apps/hype.svg"
|
||||
install -Dm644 pkgbuild/hype.desktop "$pkgdir/usr/share/applications/hype.desktop"
|
||||
install -Dm644 README.md "$pkgdir/usr/share/doc/$pkgname/README.md"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
post_install() {
|
||||
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q
|
||||
command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
post_install
|
||||
}
|
||||
|
||||
post_remove() {
|
||||
post_install
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
pkgname="hyprland-preview-share-picker"
|
||||
pkgver=0.2.1
|
||||
pkgrel=1
|
||||
pkgrel=2
|
||||
pkgdesc="An alternative share picker for hyprland with window and monitor previews"
|
||||
arch=(x86_64 aarch64)
|
||||
url="https://github.com/WhySoBad/hyprland-preview-share-picker"
|
||||
@@ -32,14 +32,14 @@ fn main() {
|
||||
}
|
||||
EOF
|
||||
|
||||
export RUSTUP_TOOLCHAIN=nightly
|
||||
export RUSTUP_TOOLCHAIN=stable
|
||||
cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
export RUSTUP_TOOLCHAIN=nightly
|
||||
export RUSTUP_TOOLCHAIN=stable
|
||||
export CARGO_TARGET_DIR=target
|
||||
|
||||
cargo build --frozen --release
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"source": "local",
|
||||
"release_ring": "fast",
|
||||
"min_release_age": "24h",
|
||||
"upstream": {
|
||||
"github": "DanWahlin/learn-omarchy",
|
||||
"checksums": "SHA256SUMS",
|
||||
"assets": {
|
||||
"any": "learn-omarchy-{pkgver}.tar.gz"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Maintainer: Dan Wahlin <dwahlin@gmail.com>
|
||||
|
||||
pkgname=learn-omarchy
|
||||
pkgver=0.2.2
|
||||
pkgrel=1
|
||||
pkgdesc="Interactive, theme-aware courses for learning Omarchy"
|
||||
arch=('any')
|
||||
url="https://github.com/DanWahlin/learn-omarchy"
|
||||
license=('MIT' 'CC-BY-4.0' 'CC0-1.0')
|
||||
depends=(
|
||||
'bash' 'coreutils' 'sudo' 'hyprland' 'mpv' 'nodejs>=22.6' 'omarchy'
|
||||
'quickshell>=0.3' 'qt6-declarative' 'qt6-multimedia' 'qt6-multimedia-ffmpeg' 'xdg-utils'
|
||||
'xdg-terminal-exec' 'nautilus'
|
||||
'ttf-liberation' 'noto-fonts-emoji'
|
||||
'grim' 'slurp' 'gpu-screen-recorder' 'util-linux' 'ffmpeg'
|
||||
)
|
||||
makedepends=('make')
|
||||
optdepends=(
|
||||
'btop: activity-monitor practice'
|
||||
'tesseract: OCR practice'
|
||||
'tesseract-data-eng: English OCR sample recognition'
|
||||
'zbar: QR recognition (zbarimg)'
|
||||
'qrencode: QR sample creation'
|
||||
'voxtype: optional dictation practice'
|
||||
)
|
||||
options=('!strip')
|
||||
source=("$pkgname-$pkgver.tar.gz::$url/releases/download/v$pkgver/$pkgname-$pkgver.tar.gz")
|
||||
sha256sums=('67f14778c2b66d56c1504695b0e11cab603f1a002570abc94b4bae9b0bec6066')
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
node tools/prepare-release.mjs --check .
|
||||
make DESTDIR="$pkgdir" PREFIX=/usr install
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Zesko
|
||||
pkgname="limine-snapper-sync"
|
||||
pkgver=1.31.0
|
||||
pkgrel=1.1
|
||||
pkgver=1.32.0
|
||||
pkgrel=1
|
||||
_gradle_version=9.7.1
|
||||
pkgdesc="Integrates Limine boot entries with Snapper snapshots."
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -31,7 +31,7 @@ makedepends=('git')
|
||||
makedepends_x86_64=('gradle')
|
||||
backup=(etc/limine-snapper-sync.conf)
|
||||
conflicts=('limine-snapper-cli' 'limine-snapper-sync-git')
|
||||
sha256sums=('ed236f1bbab966950bf11ba5a7958e97a76e66db7fd647b7737bab4b48c9fc40')
|
||||
sha256sums=('6bcc1d3ace58030204260a9a4d40d500c4822416be1b1c6edd153d1df0796b3d')
|
||||
sha256sums_x86_64=('e0be791c8fda4d03b6b0a0cb824fef3149736170057b3a515252b44419606af0')
|
||||
sha256sums_aarch64=('b4580d9f223d0a4b3a1757e58b18ff4c1db950e67e105fc5cb741457d2384a71'
|
||||
'acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a')
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"source": "local",
|
||||
"release_ring": "fast",
|
||||
"sync": false
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
# Maintainer: Spencer Bull <spencerbull2554@gmail.com>
|
||||
#
|
||||
# Self-retiring shim: ships Arch's linux-firmware-cirrus 20260910-2 payload to
|
||||
# the stable channel while stable's pinned Arch snapshot is still on
|
||||
# linux-firmware 20260810-2 (which lacks the Dell XPS 13 DX13260 / 1028:0e54
|
||||
# CS35L56 amplifier firmware aliases, leaving that machine's speakers silent).
|
||||
#
|
||||
# Nothing is rebuilt. The signed Arch package is verified against the Arch
|
||||
# packager key and its payload reinstalled as-is, minus the files that Arch
|
||||
# moved out of linux-firmware-other in 20260910 (the cs42l45 SDCA tree): on
|
||||
# the stable snapshot those are still owned by linux-firmware-other 20260810-2
|
||||
# and would conflict, so they are left to that package.
|
||||
#
|
||||
# Versioning is deliberate: 20260810-3 orders above the snapshot's 20260810-2
|
||||
# and BELOW Arch's real 20260910-2, so as soon as the stable snapshot advances
|
||||
# pacman replaces this shim with the genuine package in the same transaction
|
||||
# that upgrades linux-firmware-other, and nothing is lost. Delete this recipe
|
||||
# once stable's snapshot is at linux-firmware >= 20260910.
|
||||
|
||||
pkgname=linux-firmware-cirrus
|
||||
pkgver=20260810
|
||||
pkgrel=3
|
||||
_fwver=20260910
|
||||
_fwrel=2
|
||||
_basever=20260810
|
||||
_baserel=2
|
||||
pkgdesc="Firmware files for Linux - Firmware for Cirrus Logic audio devices (Arch - payload, stable-snapshot shim)"
|
||||
arch=('any')
|
||||
url="https://gitlab.com/kernel-firmware/linux-firmware"
|
||||
license=('LicenseRef-WHENCE' 'LicenseRef-cirrus')
|
||||
depends=('linux-firmware-whence')
|
||||
options=('!strip' '!debug')
|
||||
_cirrus="linux-firmware-cirrus-${_fwver}-${_fwrel}-any.pkg.tar.zst"
|
||||
_other="linux-firmware-other-${_basever}-${_baserel}-any.pkg.tar.zst"
|
||||
source=(
|
||||
"https://archive.archlinux.org/packages/l/linux-firmware-cirrus/${_cirrus}"
|
||||
"https://archive.archlinux.org/packages/l/linux-firmware-cirrus/${_cirrus}.sig"
|
||||
"https://archive.archlinux.org/packages/l/linux-firmware-other/${_other}"
|
||||
"https://archive.archlinux.org/packages/l/linux-firmware-other/${_other}.sig"
|
||||
)
|
||||
noextract=("${_cirrus}" "${_other}")
|
||||
sha256sums=('70100c551b079bd8abec3d9c96a16defd04766b2a4afc6d7be9128d37e9840f7'
|
||||
'SKIP'
|
||||
'b0f016ee0d0532b977211b0cbb630bca75184f68a9ace82675eb3cf9acce4f6c'
|
||||
'SKIP')
|
||||
# Jan Alexander Steffens (heftig) <heftig@archlinux.org>, Arch Linux packager
|
||||
validpgpkeys=('83BC8889351B5DEBBB68416EB8AC08600F108CDF')
|
||||
|
||||
package() {
|
||||
# Payload only; makepkg regenerates .PKGINFO/.MTREE/.BUILDINFO.
|
||||
bsdtar -xf "${srcdir}/${_cirrus}" -C "${pkgdir}" \
|
||||
--exclude='.PKGINFO' --exclude='.MTREE' --exclude='.BUILDINFO' \
|
||||
--exclude='.INSTALL' --exclude='.CHANGELOG'
|
||||
|
||||
# Drop every file the snapshot's linux-firmware-other still owns.
|
||||
local f
|
||||
while IFS= read -r f; do
|
||||
[[ -e "${pkgdir}/${f}" || -L "${pkgdir}/${f}" ]] && rm -f "${pkgdir}/${f}"
|
||||
done < <(bsdtar -tf "${srcdir}/${_other}" | grep -v '^\.' | grep -v '/$')
|
||||
|
||||
# Remove directories emptied by the step above.
|
||||
find "${pkgdir}/usr/lib/firmware" -depth -type d -empty -delete
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEZXeS9hYJKwYBBAHaRw8BAQdAT04Na8ee0UltkhyNi2RGHYdjZDgg+X/K8Jix
|
||||
dSSQ+Ni0NkphbiBBbGV4YW5kZXIgU3RlZmZlbnMgKGhlZnRpZykgPGhlZnRpZ0Bh
|
||||
cmNobGludXgub3JnPoiQBBMWCgA4AhsDAheAFiEEg7yIiTUbXeu7aEFuuKwIYA8Q
|
||||
jN8FAmWq/kcFCwkIBwMFFQoJCAsFFgIDAQACHgUACgkQuKwIYA8QjN+2qAEAh/RL
|
||||
Zq7Hmqv/z09yq0m6IEb0kbXaW50POi/V+2VcJ9wBAN5Ik/fFgnGMlvZF7Rugu37o
|
||||
2fk7jnUVsWJca9QmytgGiHUEEBYKAB0WIQSZtmGEcqOzuBQYW67X09gjuIvbmwUC
|
||||
aYWy0QAKCRDX09gjuIvbm7vJAP9xqmmI8jNGEUQNidh9yZCmVOr3vT5/sUcHGo0J
|
||||
08o/TgD/Wix2/4DHfnk6fu+onERrK5uF9BAacERnCsG5lMWQ2wSJAjMEEAEKAB0W
|
||||
IQSR/+BwDoBhnOtzI1yojiPjd1FOAAUCZa0cywAKCRCojiPjd1FOAIKbEACipPSS
|
||||
sA2G7ntHRGEHSWKgqEKseGGr7kflVdsmJn1tjKI8/VGKa77NkCRgqIJRwmE9m9+F
|
||||
Cx+a3ILmMOxsjj5RCVFce9NJuscVGHaphZcp7Z0MVoR9hhtnsyjWk/CYOAv+JLKq
|
||||
NTYhdmat+ixY4fwPzjdV6sxCDL/s6Fci0zPLUam7QVr9LIS4U3UH7smkKj6jM+G/
|
||||
sEn0QM02EKy2iJLlbPNN3pppYWqZ5p9xXeB6EJ89JvZMI3k92xy456JjkCgLN860
|
||||
NPmdmnLLtlrGWJRgNK6+iaFjLt/BL9gU8aGe+K3ONXES2k7iZnh+oLAEV8Z07dgv
|
||||
Gd0o+OFEPrC8kETbQK45r1yAjZVO+tp4dSxvV/BD+7KhUXAZnOKWLaOMomfsG17E
|
||||
KKa894cBLJG7LWN/d/Uk9fjfjd4ZYbSpIALJiEoKrm1ytj2KgnxKveTtY69i63/N
|
||||
0BpNVrkYIJffWR6zSosC8geAWfqm7pR6JARUAZrw0YtJbluDrRgOO0XFn8hDqRUm
|
||||
FPWgXuvqNdR2JyD4aB87LKGhzVFzQvbHa+S4sG7+w5nWQB0Eca+hiVpJDpMYjoU+
|
||||
f+L3yUb6POwvUJe7VT/2PYOwidnV3guTevnn9a4erKoW/6wKAr13cW+KTKTR0bdC
|
||||
S0UTOWbJnbi2Hfhyr7NZgs4T4OcpH3kj+R4WPIkCMwQQAQoAHRYhBNiv3aB6W27f
|
||||
p9jM2tbQVfknhD8cBQJlg4C5AAoJENbQVfknhD8cpPQP/19uAVMaG1lQNaAK9XWT
|
||||
Z1/lAr6sxYT6B2+MqnRtbkr4Gh3ts7Ey5BI39HxNWRIUGUt7pq4FjCQxWeJC9mfp
|
||||
/hqj9rl1s32lbBzevbkjESro+cHPfrv0vsVlwJA2W3rURQlQzbEq3fvDzc/wz4sN
|
||||
vgQDiUlxH5JYXZ5OexsDATLyfHNpJh+4NxqB24axjDe/1ZK8hoYl+eX46dP9JKWB
|
||||
F8GA3Ebwst3de/81oNngBjDgNPju6cvgykoT2jCBn4asp1xKekZh5ZbRG40jAeoQ
|
||||
QAvEgTxIbwNf4HBVhvGjQ6G5lCNO6gQonq1X4UbHgH8tRGSSgnz2yDAdcxtaj1eC
|
||||
e5BMhjuoHuxS4DCtR97Dtn7YjrYoVus5eMkhEZGuWKK4hkggsLbyUx5llxZxLXPD
|
||||
mBAYLkqgZsHgiqLeHAdrEmAFaRfskVg0MzfCcEE9StWnWf0ixk3thuwQAaPI4GCB
|
||||
nNLnmqCcOyCN1Qa3iXjdOzp5bU0qwFi/qFQagq0nu8sJim7q0g0Bk7J+iGRht3no
|
||||
L5iT9d+8CQaN1it+L+elSYfrr/LamghRvh9epOtGUVH3GQYS4Bgo2rgktGXKtcX+
|
||||
P/jR/aM034g8VPlbV+Kas/c6mIk9JzKOvJJ4+Lpvr0ZzRG32ez9dAlDogE3xASi6
|
||||
sMWbY+t4unGs+nY3SqIOyHLTiHUEEBYKAB0WIQRp5kceOuBlKXUpgy5roPWiA39P
|
||||
QQUCZX7ZYAAKCRBroPWiA39PQadvAQD7F/N3xuyWogrJV7TMZk2PFteviEW2Dv9d
|
||||
dSUGasK3dQEAxf3HxRDvrv3yJLhgNKa+ksr4bBBmruvilpWS+X4InwKIdQQQFgoA
|
||||
HRYhBDVy+iobBn8ixYrxVfi4IbQqb9zXBQJlfKbrAAoJEPi4IbQqb9zXe7MBAIzF
|
||||
QqdV8CJXYIcZJtUUIQ7a/AN2enHBpoa/qXEre5bAAP4uNEUMKiDZRpHAh/KmqarM
|
||||
vF+c1BOpEJbQsPqv0L5hDIh1BBAWCgAdFiEEKsCkLvsLXLx6BALtTclbbXvpiS4F
|
||||
AmV8nsgACgkQTclbbXvpiS6bpwD/W0sMOH4lmR4t9Sc8hJB+uBLGYxzoNIgaNa5x
|
||||
vbdm5hwBAIPYr1SVl0+yghsxg5k75jStRL2S5MZW2iSV3ynNLTkFiHkEEBYKACEW
|
||||
IQSi/zo2qqVmVBCQZKsZgC+LDXD8MAUCZXe6yAMFAngACgkQGYAviw1w/DCmCAD8
|
||||
Cfvn8O+N/AJTOKY8lZzk+OSX3tSTQTOUiLHKRl+RX6IA/1Bku44c1YJVZ+RhWkGQ
|
||||
n0C8ZN/DYzHh9JInl3blLcIMtDhKYW4gQWxleGFuZGVyIFN0ZWZmZW5zIChoZWZ0
|
||||
aWcpIDxqYW4uc3RlZmZlbnNAZ21haWwuY29tPoiTBBMWCgA7AhsDAheAAhkBFiEE
|
||||
g7yIiTUbXeu7aEFuuKwIYA8QjN8FAmWq/kIFCwkIBwMFFQoJCAsFFgIDAQACHgUA
|
||||
CgkQuKwIYA8QjN+ySAD+PI99JJsFWz2CaS3enxjUMCWJZJvSV9G1FqmeTKtH95oA
|
||||
/ismVRjBbwbCrDDEsZVIK3NeRyRyhiWIVFXWix/KnH4CiHkEEBYKACEWIQSi/zo2
|
||||
qqVmVBCQZKsZgC+LDXD8MAUCZXe6xQMFAngACgkQGYAviw1w/DDnzAD6AwROKYI8
|
||||
7DZ6a1onZeR5wOV50bt2LCB4XxNiupHcpLMA/i4dmwa4Bkzyh/h+v0kN2PSssueX
|
||||
7kFPNcnyhe3KbUUDuDMEZXeUSxYJKwYBBAHaRw8BAQdAkvIbYwde3OFqoAy6QOO9
|
||||
BPwFNCll8tgQ6iAmQMkOjtWIeAQYFgoAIBYhBIO8iIk1G13ru2hBbrisCGAPEIzf
|
||||
BQJld5RLAhsgAAoJELisCGAPEIzfhU8A/3NZzIEk3dmCAL0XLtylcFp/HExnN+5Q
|
||||
RGmT0+SzzuGaAP9ozoMlSjtcGLAZMglLk8/mYzKveR89RJlB0cZtUU6UArg4BGV3
|
||||
kvYSCisGAQQBl1UBBQEBB0Dh/7CubQh/MabODq3IcoqeGUzEGUPU8GXCVrDmPHih
|
||||
WQMBCAeIeAQYFgoAIBYhBIO8iIk1G13ru2hBbrisCGAPEIzfBQJld5L2AhsMAAoJ
|
||||
ELisCGAPEIzfao0A/AiJPB4igiyHjPgR8OpKh4Nz+pwmFrD/j5l2YC0Xi2dOAP4j
|
||||
LDEa1VCNNhq7vWA8SqUjareBzHpwlG2ObUwYxORjBQ==
|
||||
=OXp6
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -0,0 +1,31 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -935,6 +935,9 @@ KBUILD_RUSTFLAGS += -Copt-level=2
|
||||
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += -Os
|
||||
KBUILD_RUSTFLAGS += -Copt-level=s
|
||||
+else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
|
||||
+KBUILD_CFLAGS += -O3
|
||||
+KBUILD_RUSTFLAGS += -Copt-level=3
|
||||
endif
|
||||
|
||||
# Always set `debug-assertions` and `overflow-checks` because their default
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -1622,6 +1622,14 @@ config CC_OPTIMIZE_FOR_SIZE
|
||||
Choosing this option will pass "-Os" to your compiler resulting
|
||||
in a smaller kernel.
|
||||
|
||||
+config CC_OPTIMIZE_FOR_PERFORMANCE_O3
|
||||
+ bool "Optimize harder for performance (-O3)"
|
||||
+ help
|
||||
+ Build with the "-O3" compiler flag: more inlining, loop
|
||||
+ unrolling and vectorization than -O2, at the cost of a larger
|
||||
+ kernel image and larger modules. Rust code is built at
|
||||
+ opt-level 3.
|
||||
+
|
||||
endchoice
|
||||
|
||||
config HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
|
||||
--- a/arch/x86/include/asm/cpufeatures.h
|
||||
+++ b/arch/x86/include/asm/cpufeatures.h
|
||||
@@ -471,6 +471,8 @@
|
||||
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
|
||||
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
|
||||
|
||||
+#define X86_FEATURE_L2_TLB_SIZE_X32 (20*32+14) /* L2 TLB sizes are encoded as multiples of 32 */
|
||||
+
|
||||
#define X86_FEATURE_GP_ON_USER_CPUID (20*32+17) /* User CPUID faulting */
|
||||
|
||||
#define X86_FEATURE_PREFETCHI (20*32+20) /* Prefetch Data/Instruction to Cache Level */
|
||||
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
|
||||
--- a/arch/x86/kernel/cpu/amd.c
|
||||
+++ b/arch/x86/kernel/cpu/amd.c
|
||||
@@ -1190,7 +1190,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
|
||||
static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
- u32 ebx, eax, ecx, edx;
|
||||
+ u32 ebx, eax, ecx, edx, shift, tmp;
|
||||
u16 mask = 0xfff;
|
||||
|
||||
if (c->x86 < 0xf)
|
||||
@@ -1199,10 +1199,12 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
if (c->extended_cpuid_level < 0x80000006)
|
||||
return;
|
||||
|
||||
+ shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
|
||||
+
|
||||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
- tlb_lld_4k = (ebx >> 16) & mask;
|
||||
- tlb_lli_4k = ebx & mask;
|
||||
+ tlb_lld_4k = ((ebx >> 16) & mask) << shift;
|
||||
+ tlb_lli_4k = (ebx & mask) << shift;
|
||||
|
||||
/*
|
||||
* K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB
|
||||
@@ -1214,16 +1216,18 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
}
|
||||
|
||||
/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
- if (!((eax >> 16) & mask))
|
||||
+ tmp = ((eax >> 16) & mask) << shift;
|
||||
+ if (!tmp)
|
||||
tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
else
|
||||
- tlb_lld_2m = (eax >> 16) & mask;
|
||||
+ tlb_lld_2m = tmp;
|
||||
|
||||
/* a 4M entry uses two 2M entries */
|
||||
tlb_lld_4m = tlb_lld_2m >> 1;
|
||||
|
||||
/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
- if (!(eax & mask)) {
|
||||
+ tmp = (eax & mask) << shift;
|
||||
+ if (!tmp) {
|
||||
/* Erratum 658 */
|
||||
if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
|
||||
tlb_lli_2m = 1024;
|
||||
@@ -1231,8 +1235,9 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
|
||||
tlb_lli_2m = eax & 0xff;
|
||||
}
|
||||
- } else
|
||||
- tlb_lli_2m = eax & mask;
|
||||
+ } else {
|
||||
+ tlb_lli_2m = tmp;
|
||||
+ }
|
||||
|
||||
tlb_lli_4m = tlb_lli_2m >> 1;
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
||||
--- a/arch/x86/kernel/cpu/common.c
|
||||
+++ b/arch/x86/kernel/cpu/common.c
|
||||
@@ -857,7 +857,7 @@ static void get_model_name(struct cpuinfo_x86 *c)
|
||||
|
||||
void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
{
|
||||
- unsigned int n, dummy, ebx, ecx, edx, l2size;
|
||||
+ unsigned int n, dummy, ebx, ecx, edx, l2size, shift __maybe_unused;
|
||||
|
||||
n = c->extended_cpuid_level;
|
||||
|
||||
@@ -877,7 +877,9 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
l2size = ecx >> 16;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
+ shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
|
||||
c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
|
||||
+ c->x86_tlbsize <<= shift;
|
||||
#else
|
||||
/* do processor-specific cache resizing */
|
||||
if (this_cpu->legacy_cache_size)
|
||||
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
--- a/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
@@ -1343,7 +1343,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
||||
|
||||
if (ttm_tt_is_populated(tt)) {
|
||||
ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
|
||||
- if (!ret) {
|
||||
+ if (ret > 0) {
|
||||
spin_lock(&bdev->lru_lock);
|
||||
ttm_resource_del_bulk_move_unevictable(bo->resource, bo);
|
||||
ttm_resource_move_to_lru_tail(bo->resource);
|
||||
BIN
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
|
||||
pkgbase=linux-omarchy-bore
|
||||
pkgver=7.2.5
|
||||
pkgrel=4
|
||||
pkgrel=6
|
||||
pkgdesc='Omarchy Linux (BORE CPU scheduler, ADIOS I/O scheduler)'
|
||||
url='https://omarchy.org'
|
||||
arch=(
|
||||
@@ -49,6 +49,7 @@ source=(
|
||||
${_rcpatch:+https://cdn.kernel.org/pub/linux/kernel/v${_major}.x/stable-review/${_rcpatch}.xz}
|
||||
${_rcpatch:+https://cdn.kernel.org/pub/linux/kernel/v${_major}.x/stable-review/${_rcpatch}.sign}
|
||||
0010-archlinux-base.patch{,.sig}
|
||||
0011-kbuild-optimize-for-performance-o3.patch{,.sig}
|
||||
0110-bore-6.8.0.patch{,.sig}
|
||||
0120-tlbpull.patch{,.sig}
|
||||
0121-smp-preempt.patch{,.sig}
|
||||
@@ -64,6 +65,7 @@ source=(
|
||||
0210-pstate.patch{,.sig}
|
||||
0211-amd-pstate-fixes.patch{,.sig}
|
||||
0212-amd-pstate-epp-cache.patch{,.sig}
|
||||
0220-x86-amd-zen5-tlb-sizes.patch{,.sig}
|
||||
0250-zsmalloc.patch{,.sig}
|
||||
0260-mglru-exec-protect.patch{,.sig}
|
||||
0270-ksm-rmap-walk.patch{,.sig}
|
||||
@@ -83,6 +85,7 @@ source=(
|
||||
0313-fuse-background-wakeup.patch{,.sig}
|
||||
0350-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch{,.sig}
|
||||
0360-gpu-mem-cgroup.patch{,.sig}
|
||||
0361-drm-ttm-swapped-out-resource-leaves-bulk-move.patch{,.sig}
|
||||
0400-drm-i915-alpm-limit-pr-alpm-to-panel-replay.patch{,.sig}
|
||||
0401-drm-i915-psr-exit-panel-replay-for-alpm-lag.patch{,.sig}
|
||||
0402-psr2-early-transport-panels.patch{,.sig}
|
||||
@@ -151,6 +154,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'6d92fb81077232b8cd1ae500b3aabc71434792e750ea6126dc095e50d4278d3e42b3cfdc3c8bc693ea14b109f6adfa3a1ed095187fc5501962fbe8f049f867bc'
|
||||
'SKIP'
|
||||
'cc2a66a097b5567e80c59b7d6c492fef5e667fc71a0390908712c69512c4136dbaf3d150b62d04eff960c796f7a94e6d0915d3b92cb336318b49f5f516a3bba6'
|
||||
'SKIP'
|
||||
'a32edb39b4ee9c0378239f4998f477fe5371e6931c188d660874b360ca6d3bdcfff71cf088bed071365627d87458eca0be625e154ca3d1e8150e5e0bdf64175c'
|
||||
'SKIP'
|
||||
'f6c00ac2400580dffe3605d2693809396e18185f0c59b21b86f1f22a1f8d6529c51e8cc2474bc40f74a96631f415da51521a8b35d5b096e9b9d164c2755fb091'
|
||||
@@ -181,6 +186,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'2f24f88d8f960148046c36222fdaaadfed2ca88c60240fa1d111430898192ca45aeaa93a3afa24ad02b11c4dc8c3904a92f17c0284396f2f43352ad934a35056'
|
||||
'SKIP'
|
||||
'e59c4da548b2ea4fd6144886e3e2e765b3e73972121e9e73dbc05c066834b2b35e6ef4c17617e77efc90260566bf7c0910d2138d8d5c1c3b6094eeac9de64cfe'
|
||||
'SKIP'
|
||||
'9809e258eb684b80d508fa2f2fa270683b62bd1412ed05a970114aaa7d84c37c0beaea51f9ff8c6ee1bc7318c4aee3725e9a1131fefb51ba700801de6ac414c5'
|
||||
'SKIP'
|
||||
'f115e8c80d723f7c24e6b1638b801cd664bef20acb1d2f6e6f5612744b916278693011782228cd3f4d0518654b8d53309bc5b06bbe8ed722fab9995f369bf548'
|
||||
@@ -219,6 +226,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'1124c5c3fd5104c886c841ead1ae9afb42683388b640b1a86523dad9919c6bd59a1f78b07ee5a213e0dca77c636a29676af0592d4ed1735ea35f282f6f23e46f'
|
||||
'SKIP'
|
||||
'15855e9c28cb0abaab7ab606904dfc84d426ccab44edae59f0e1f092202b80525929f8d394d04ca1513d1d5dfc2cfc108a66a9c1cb42b9966c6417562ef20689'
|
||||
'SKIP'
|
||||
'505bf01a9d6b0926b557b673bb686d1a4ff73ee70539991e52272fbf58aad3ea25cf5ffc5c2d094a2d5e78b18a1a134f2ab530f595073a2d3eba9ff2c1418e1e'
|
||||
'SKIP'
|
||||
'b33b46c37f12f7650a67c3731b87ff84add1ac8623cc96b52223a1ef9946bcaa990ed7c7036674e228335f57ec9ed421ea4d6c1dd72d19b516215d9ac2c7c3ee'
|
||||
@@ -333,13 +342,15 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'b69cf36cc5633e507866e67f59557646dda7d6ea436b145f3f3356c4b12e1300c94977a7d1214835f2476c94a30dd672076241b920d96d744fbc199539df506f'
|
||||
'SKIP')
|
||||
b2sums_x86_64=('54148fc55a2b611f84f62d0b1c19caf911e029cd29bda6f032b15cc2f3484a1cc648af63e101eb293b048b54df4a0efacdb39cbbaa5b13d8ea1dfc22b981ec6b')
|
||||
b2sums_x86_64=('f69a306213a769710e3429817239746406e115af29f34f37514119eb49f973c86953379b68d3df89700bef7f86e3ec43eb91d5f5821f2a8eae7f28dba589d265')
|
||||
|
||||
# https://www.kernel.org/pub/linux/kernel/v7.x/sha256sums.asc
|
||||
sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'95f3e9209629044028373af987dc0e270a5a15acb8c8e49c5f05057220c75fe2'
|
||||
'SKIP'
|
||||
'6cf74fc3f28a751354187b6cf610c3e43cf9088b5f730b68dbb575828c3a7478'
|
||||
'SKIP'
|
||||
'daf0aaebff3cf4679d0bb8137ace6c9a2de62f75aa4655a0a02ddf759f3c7f26'
|
||||
'SKIP'
|
||||
'a9171e731d08a454a50174889af8936fab962b33c37c67169b0cdf21b0b80821'
|
||||
@@ -370,6 +381,8 @@ sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'66eb2c49dbf708cc781d411d0e44ed613480f0ef66d522272929d9cb7bb21e93'
|
||||
'SKIP'
|
||||
'718b40e15350049e03c0ed281b9257fca5432b8dec2e0e145e8b26507ee8892d'
|
||||
'SKIP'
|
||||
'b7ba949eea77e169aceb2c401d4eb83a7413aab6f15ee2a7ab1a96352f0aa12d'
|
||||
'SKIP'
|
||||
'341424b925d506869793686e22ea8f095a34048595ebebec409c0a7bbd346ca2'
|
||||
@@ -408,6 +421,8 @@ sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'e303da14a3c8a15fd1cb45394138f03dd16e66d2ac0d1ebcd933977df937d771'
|
||||
'SKIP'
|
||||
'503eba8d7a80b978fccdaac798f57cbb6cd2b2b04fd04c46399daa004b6646dc'
|
||||
'SKIP'
|
||||
'1f0c958b64ba48b8dc8b5548e1ad1934b8d4903fc16fec15014759e3681ea275'
|
||||
'SKIP'
|
||||
'47994d576008a377de612ed77e6b2e7bc6b24ad3a30a6d157646d380ae323142'
|
||||
|
||||
@@ -278,8 +278,9 @@ CONFIG_BOOT_CONFIG=y
|
||||
# CONFIG_BOOT_CONFIG_EMBED is not set
|
||||
CONFIG_CMDLINE_LOG_WRAP_IDEAL_LEN=1021
|
||||
CONFIG_INITRAMFS_PRESERVE_MTIME=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y
|
||||
CONFIG_LD_ORPHAN_WARN=y
|
||||
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
|
||||
CONFIG_SYSCTL=y
|
||||
@@ -11872,7 +11873,7 @@ CONFIG_INIT_STACK_ALL_ZERO=y
|
||||
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
|
||||
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
|
||||
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
|
||||
CONFIG_ZERO_CALL_USED_REGS=y
|
||||
# CONFIG_ZERO_CALL_USED_REGS is not set
|
||||
# end of Memory initialization
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -935,6 +935,9 @@ KBUILD_RUSTFLAGS += -Copt-level=2
|
||||
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += -Os
|
||||
KBUILD_RUSTFLAGS += -Copt-level=s
|
||||
+else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
|
||||
+KBUILD_CFLAGS += -O3
|
||||
+KBUILD_RUSTFLAGS += -Copt-level=3
|
||||
endif
|
||||
|
||||
# Always set `debug-assertions` and `overflow-checks` because their default
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -1622,6 +1622,14 @@ config CC_OPTIMIZE_FOR_SIZE
|
||||
Choosing this option will pass "-Os" to your compiler resulting
|
||||
in a smaller kernel.
|
||||
|
||||
+config CC_OPTIMIZE_FOR_PERFORMANCE_O3
|
||||
+ bool "Optimize harder for performance (-O3)"
|
||||
+ help
|
||||
+ Build with the "-O3" compiler flag: more inlining, loop
|
||||
+ unrolling and vectorization than -O2, at the cost of a larger
|
||||
+ kernel image and larger modules. Rust code is built at
|
||||
+ opt-level 3.
|
||||
+
|
||||
endchoice
|
||||
|
||||
config HAVE_LD_DEAD_CODE_DATA_ELIMINATION
|
||||
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
|
||||
--- a/arch/x86/include/asm/cpufeatures.h
|
||||
+++ b/arch/x86/include/asm/cpufeatures.h
|
||||
@@ -471,6 +471,8 @@
|
||||
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
|
||||
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
|
||||
|
||||
+#define X86_FEATURE_L2_TLB_SIZE_X32 (20*32+14) /* L2 TLB sizes are encoded as multiples of 32 */
|
||||
+
|
||||
#define X86_FEATURE_GP_ON_USER_CPUID (20*32+17) /* User CPUID faulting */
|
||||
|
||||
#define X86_FEATURE_PREFETCHI (20*32+20) /* Prefetch Data/Instruction to Cache Level */
|
||||
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
|
||||
--- a/arch/x86/kernel/cpu/amd.c
|
||||
+++ b/arch/x86/kernel/cpu/amd.c
|
||||
@@ -1190,7 +1190,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
|
||||
static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
- u32 ebx, eax, ecx, edx;
|
||||
+ u32 ebx, eax, ecx, edx, shift, tmp;
|
||||
u16 mask = 0xfff;
|
||||
|
||||
if (c->x86 < 0xf)
|
||||
@@ -1199,10 +1199,12 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
if (c->extended_cpuid_level < 0x80000006)
|
||||
return;
|
||||
|
||||
+ shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
|
||||
+
|
||||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
- tlb_lld_4k = (ebx >> 16) & mask;
|
||||
- tlb_lli_4k = ebx & mask;
|
||||
+ tlb_lld_4k = ((ebx >> 16) & mask) << shift;
|
||||
+ tlb_lli_4k = (ebx & mask) << shift;
|
||||
|
||||
/*
|
||||
* K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB
|
||||
@@ -1214,16 +1216,18 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
}
|
||||
|
||||
/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
- if (!((eax >> 16) & mask))
|
||||
+ tmp = ((eax >> 16) & mask) << shift;
|
||||
+ if (!tmp)
|
||||
tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
else
|
||||
- tlb_lld_2m = (eax >> 16) & mask;
|
||||
+ tlb_lld_2m = tmp;
|
||||
|
||||
/* a 4M entry uses two 2M entries */
|
||||
tlb_lld_4m = tlb_lld_2m >> 1;
|
||||
|
||||
/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
- if (!(eax & mask)) {
|
||||
+ tmp = (eax & mask) << shift;
|
||||
+ if (!tmp) {
|
||||
/* Erratum 658 */
|
||||
if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
|
||||
tlb_lli_2m = 1024;
|
||||
@@ -1231,8 +1235,9 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
|
||||
tlb_lli_2m = eax & 0xff;
|
||||
}
|
||||
- } else
|
||||
- tlb_lli_2m = eax & mask;
|
||||
+ } else {
|
||||
+ tlb_lli_2m = tmp;
|
||||
+ }
|
||||
|
||||
tlb_lli_4m = tlb_lli_2m >> 1;
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
||||
--- a/arch/x86/kernel/cpu/common.c
|
||||
+++ b/arch/x86/kernel/cpu/common.c
|
||||
@@ -857,7 +857,7 @@ static void get_model_name(struct cpuinfo_x86 *c)
|
||||
|
||||
void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
{
|
||||
- unsigned int n, dummy, ebx, ecx, edx, l2size;
|
||||
+ unsigned int n, dummy, ebx, ecx, edx, l2size, shift __maybe_unused;
|
||||
|
||||
n = c->extended_cpuid_level;
|
||||
|
||||
@@ -877,7 +877,9 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
l2size = ecx >> 16;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
+ shift = !!cpu_has(c, X86_FEATURE_L2_TLB_SIZE_X32) * 5;
|
||||
c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
|
||||
+ c->x86_tlbsize <<= shift;
|
||||
#else
|
||||
/* do processor-specific cache resizing */
|
||||
if (this_cpu->legacy_cache_size)
|
||||
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
--- a/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
|
||||
@@ -1343,7 +1343,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
|
||||
|
||||
if (ttm_tt_is_populated(tt)) {
|
||||
ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
|
||||
- if (!ret) {
|
||||
+ if (ret > 0) {
|
||||
spin_lock(&bdev->lru_lock);
|
||||
ttm_resource_del_bulk_move_unevictable(bo->resource, bo);
|
||||
ttm_resource_move_to_lru_tail(bo->resource);
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
|
||||
pkgbase=linux-omarchy
|
||||
pkgver=7.2.5
|
||||
pkgrel=4
|
||||
pkgrel=6
|
||||
pkgdesc='Omarchy Linux'
|
||||
url='https://omarchy.org'
|
||||
arch=(
|
||||
@@ -49,6 +49,7 @@ source=(
|
||||
${_rcpatch:+https://cdn.kernel.org/pub/linux/kernel/v${_major}.x/stable-review/${_rcpatch}.xz}
|
||||
${_rcpatch:+https://cdn.kernel.org/pub/linux/kernel/v${_major}.x/stable-review/${_rcpatch}.sign}
|
||||
0010-archlinux-base.patch{,.sig}
|
||||
0011-kbuild-optimize-for-performance-o3.patch{,.sig}
|
||||
0120-tlbpull.patch{,.sig}
|
||||
0121-smp-preempt.patch{,.sig}
|
||||
0130-sched-detach-tasks.patch{,.sig}
|
||||
@@ -63,6 +64,7 @@ source=(
|
||||
0210-pstate.patch{,.sig}
|
||||
0211-amd-pstate-fixes.patch{,.sig}
|
||||
0212-amd-pstate-epp-cache.patch{,.sig}
|
||||
0220-x86-amd-zen5-tlb-sizes.patch{,.sig}
|
||||
0250-zsmalloc.patch{,.sig}
|
||||
0260-mglru-exec-protect.patch{,.sig}
|
||||
0270-ksm-rmap-walk.patch{,.sig}
|
||||
@@ -82,6 +84,7 @@ source=(
|
||||
0313-fuse-background-wakeup.patch{,.sig}
|
||||
0350-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch{,.sig}
|
||||
0360-gpu-mem-cgroup.patch{,.sig}
|
||||
0361-drm-ttm-swapped-out-resource-leaves-bulk-move.patch{,.sig}
|
||||
0400-drm-i915-alpm-limit-pr-alpm-to-panel-replay.patch{,.sig}
|
||||
0401-drm-i915-psr-exit-panel-replay-for-alpm-lag.patch{,.sig}
|
||||
0402-psr2-early-transport-panels.patch{,.sig}
|
||||
@@ -150,6 +153,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'6d92fb81077232b8cd1ae500b3aabc71434792e750ea6126dc095e50d4278d3e42b3cfdc3c8bc693ea14b109f6adfa3a1ed095187fc5501962fbe8f049f867bc'
|
||||
'SKIP'
|
||||
'cc2a66a097b5567e80c59b7d6c492fef5e667fc71a0390908712c69512c4136dbaf3d150b62d04eff960c796f7a94e6d0915d3b92cb336318b49f5f516a3bba6'
|
||||
'SKIP'
|
||||
'f6c00ac2400580dffe3605d2693809396e18185f0c59b21b86f1f22a1f8d6529c51e8cc2474bc40f74a96631f415da51521a8b35d5b096e9b9d164c2755fb091'
|
||||
'SKIP'
|
||||
'6aa6ea3690f3e4e145818650537cd110d33720d662af0b3660d95e15a3f91e48c993e31117c0a2fde852f55a77a83e3a50a1a95c0df78a33ae75d43d46a9fe15'
|
||||
@@ -178,6 +183,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'2f24f88d8f960148046c36222fdaaadfed2ca88c60240fa1d111430898192ca45aeaa93a3afa24ad02b11c4dc8c3904a92f17c0284396f2f43352ad934a35056'
|
||||
'SKIP'
|
||||
'e59c4da548b2ea4fd6144886e3e2e765b3e73972121e9e73dbc05c066834b2b35e6ef4c17617e77efc90260566bf7c0910d2138d8d5c1c3b6094eeac9de64cfe'
|
||||
'SKIP'
|
||||
'9809e258eb684b80d508fa2f2fa270683b62bd1412ed05a970114aaa7d84c37c0beaea51f9ff8c6ee1bc7318c4aee3725e9a1131fefb51ba700801de6ac414c5'
|
||||
'SKIP'
|
||||
'f115e8c80d723f7c24e6b1638b801cd664bef20acb1d2f6e6f5612744b916278693011782228cd3f4d0518654b8d53309bc5b06bbe8ed722fab9995f369bf548'
|
||||
@@ -216,6 +223,8 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'1124c5c3fd5104c886c841ead1ae9afb42683388b640b1a86523dad9919c6bd59a1f78b07ee5a213e0dca77c636a29676af0592d4ed1735ea35f282f6f23e46f'
|
||||
'SKIP'
|
||||
'15855e9c28cb0abaab7ab606904dfc84d426ccab44edae59f0e1f092202b80525929f8d394d04ca1513d1d5dfc2cfc108a66a9c1cb42b9966c6417562ef20689'
|
||||
'SKIP'
|
||||
'505bf01a9d6b0926b557b673bb686d1a4ff73ee70539991e52272fbf58aad3ea25cf5ffc5c2d094a2d5e78b18a1a134f2ab530f595073a2d3eba9ff2c1418e1e'
|
||||
'SKIP'
|
||||
'b33b46c37f12f7650a67c3731b87ff84add1ac8623cc96b52223a1ef9946bcaa990ed7c7036674e228335f57ec9ed421ea4d6c1dd72d19b516215d9ac2c7c3ee'
|
||||
@@ -330,13 +339,15 @@ b2sums=('48551bee71cd02815136fb8abe7da4464c2e17c89ef35cb0c0530c8b969fe12127ca97a
|
||||
'SKIP'
|
||||
'b69cf36cc5633e507866e67f59557646dda7d6ea436b145f3f3356c4b12e1300c94977a7d1214835f2476c94a30dd672076241b920d96d744fbc199539df506f'
|
||||
'SKIP')
|
||||
b2sums_x86_64=('11bfedf70dc9366a42b42573a3677e348fcd7b253ce13118036a75190e6c9372f9549589ff2dbfac5b976fc15d11a1b193baaee2135d331ca90f8a9a9a6e1462')
|
||||
b2sums_x86_64=('5cbc3cba5e3abe4c77a54aeb2015b04e39dc80351accaa7c268da3e67577c0ad47109b8693bf2dee8d5366d0a0df3e6439c32d18fcf5ea07345bfcf517e5036d')
|
||||
|
||||
# https://www.kernel.org/pub/linux/kernel/v7.x/sha256sums.asc
|
||||
sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'95f3e9209629044028373af987dc0e270a5a15acb8c8e49c5f05057220c75fe2'
|
||||
'SKIP'
|
||||
'6cf74fc3f28a751354187b6cf610c3e43cf9088b5f730b68dbb575828c3a7478'
|
||||
'SKIP'
|
||||
'a9171e731d08a454a50174889af8936fab962b33c37c67169b0cdf21b0b80821'
|
||||
'SKIP'
|
||||
'6a27e1b363f1bb133b9905f84b00e4d01885cac84858db46bdbf764849c9984b'
|
||||
@@ -365,6 +376,8 @@ sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'66eb2c49dbf708cc781d411d0e44ed613480f0ef66d522272929d9cb7bb21e93'
|
||||
'SKIP'
|
||||
'718b40e15350049e03c0ed281b9257fca5432b8dec2e0e145e8b26507ee8892d'
|
||||
'SKIP'
|
||||
'b7ba949eea77e169aceb2c401d4eb83a7413aab6f15ee2a7ab1a96352f0aa12d'
|
||||
'SKIP'
|
||||
'341424b925d506869793686e22ea8f095a34048595ebebec409c0a7bbd346ca2'
|
||||
@@ -403,6 +416,8 @@ sha256sums=('55ddf0df8325d9dad96fcff7bd93977d22e3f50af06527572af59b77c7632b78'
|
||||
'SKIP'
|
||||
'e303da14a3c8a15fd1cb45394138f03dd16e66d2ac0d1ebcd933977df937d771'
|
||||
'SKIP'
|
||||
'503eba8d7a80b978fccdaac798f57cbb6cd2b2b04fd04c46399daa004b6646dc'
|
||||
'SKIP'
|
||||
'1f0c958b64ba48b8dc8b5548e1ad1934b8d4903fc16fec15014759e3681ea275'
|
||||
'SKIP'
|
||||
'47994d576008a377de612ed77e6b2e7bc6b24ad3a30a6d157646d380ae323142'
|
||||
|
||||
@@ -277,8 +277,9 @@ CONFIG_BOOT_CONFIG=y
|
||||
# CONFIG_BOOT_CONFIG_EMBED is not set
|
||||
CONFIG_CMDLINE_LOG_WRAP_IDEAL_LEN=1021
|
||||
CONFIG_INITRAMFS_PRESERVE_MTIME=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y
|
||||
CONFIG_LD_ORPHAN_WARN=y
|
||||
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
|
||||
CONFIG_SYSCTL=y
|
||||
@@ -11869,7 +11870,7 @@ CONFIG_INIT_STACK_ALL_ZERO=y
|
||||
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
|
||||
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
|
||||
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
|
||||
CONFIG_ZERO_CALL_USED_REGS=y
|
||||
# CONFIG_ZERO_CALL_USED_REGS is not set
|
||||
# end of Memory initialization
|
||||
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: noureddinex
|
||||
pkgname=lmstudio-bin
|
||||
pkgver=0.4.24
|
||||
pkgrel=2
|
||||
pkgver=0.4.25
|
||||
pkgrel=1
|
||||
_build=1
|
||||
_pkgver=${pkgver}-${_build}
|
||||
pkgdesc="LM Studio - A desktop app for exploring and running large language models locally"
|
||||
@@ -16,9 +16,7 @@ conflicts=(lmstudio)
|
||||
source=("https://installers.lmstudio.ai/linux/x64/${_pkgver}/LM-Studio-${_pkgver}-x64.AppImage"
|
||||
"lmstudio.png"
|
||||
"lmstudio.desktop")
|
||||
sha256sums=('17cb8ac6374f9182fc127efae20680265e3c4c17d96eadf147eb5fe6111a9353'
|
||||
'9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5'
|
||||
'635dec12f3e3a57136b9e6fd7c2839ed6da7287fa55b482d64debf6eacf36baa')
|
||||
sha256sums=('eca467446c833824697e8befab300fe5269fdf984e3ee4385fcbad8502f07c53' '9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5' '635dec12f3e3a57136b9e6fd7c2839ed6da7287fa55b482d64debf6eacf36baa')
|
||||
|
||||
prepare() {
|
||||
chmod +x "${srcdir}/${source[0]##*/}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Maintainer: Jeff Dickey <releases@mise.jdx.dev>
|
||||
pkgname=mise-bin
|
||||
pkgver=2026.9.9
|
||||
pkgver=2026.9.12
|
||||
pkgrel=1
|
||||
pkgdesc="dev tools, env vars, task runner"
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -14,8 +14,8 @@ provides=('mise')
|
||||
conflicts=('mise')
|
||||
source_x86_64=("https://github.com/jdx/mise/releases/download/v${pkgver}/mise-v${pkgver}-linux-x64.tar.xz")
|
||||
source_aarch64=("https://github.com/jdx/mise/releases/download/v${pkgver}/mise-v${pkgver}-linux-arm64.tar.xz")
|
||||
sha256sums_x86_64=('ed3ee9b7331182e57f77230cf6af64d90e6e1a01e2c3e4749568ea335837c0fb')
|
||||
sha256sums_aarch64=('09d0489db27c173d1427b4248e3e1fbf18b00ccc1d887d8746f1d8b311903a50')
|
||||
sha256sums_x86_64=('30c79a0a24d8f0ad80e6c9b11ec54816be2a9b77e7eeae32c1267a5b9d34d3d7')
|
||||
sha256sums_aarch64=('7bc2a5558b787a33f22e4b5955cfec58871ad3723658418ad3d2cdf5a0e693b9')
|
||||
|
||||
package() {
|
||||
install -Dm755 "${srcdir}/mise/bin/mise" "${pkgdir}/usr/bin/mise"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"source": "local"
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Maintainer: David Heinemeier Hansson <david@hey.com>
|
||||
|
||||
pkgname=monologue
|
||||
pkgver=0.1.0
|
||||
pkgrel=3
|
||||
pkgdesc='A simple, theme-synced webcam recorder for Omarchy'
|
||||
arch=('x86_64' 'aarch64')
|
||||
url='https://github.com/omacom/monologue'
|
||||
license=('MIT')
|
||||
install='monologue.install'
|
||||
options=('!debug')
|
||||
depends=(
|
||||
'ffmpeg'
|
||||
'hicolor-icon-theme'
|
||||
'libpulse'
|
||||
'qt6-base'
|
||||
'qt6-declarative'
|
||||
'qt6-multimedia>=6.8'
|
||||
'xdg-desktop-portal'
|
||||
)
|
||||
makedepends=('gcc' 'make' 'pkgconf')
|
||||
optdepends=('omacut: trim recordings directly from Monologue')
|
||||
# Pin the published source until a tagged release is available.
|
||||
_commit=23e0844f60feef2f9d2cf2c9d89f13eb0bf5adef
|
||||
source=("$pkgname-$_commit.tar.gz::$url/archive/$_commit.tar.gz")
|
||||
sha256sums=('1a04b9e47b29846e9135d110978f7f35c0274f7361729f0b6ac03796499c0ad6')
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$pkgname-$_commit"
|
||||
./bin/build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$pkgname-$_commit"
|
||||
|
||||
install -Dm755 build/monologue "$pkgdir/usr/bin/monologue"
|
||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||
install -Dm644 pkgbuild/monologue.svg "$pkgdir/usr/share/icons/hicolor/scalable/apps/monologue.svg"
|
||||
install -Dm644 pkgbuild/monologue.desktop "$pkgdir/usr/share/applications/monologue.desktop"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
post_install() {
|
||||
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q
|
||||
command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
post_install
|
||||
}
|
||||
|
||||
post_remove() {
|
||||
post_install
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"source": "local",
|
||||
"channels": [
|
||||
"edge"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
Copyright Arch Linux Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,240 @@
|
||||
# Maintainer: Sven-Hendrik Haase <svenstaro@archlinux.org>
|
||||
# Maintainer: Peter Jung <ptr1337@archlinux.org>
|
||||
# Contributor: James Rayner <iphitus@gmail.com>
|
||||
# Contributor: Vasiliy Stelmachenok <ventureo@yandex.ru>
|
||||
# Contributor: Thomas Baechler <thomas@archlinux.org>
|
||||
|
||||
pkgbase=nvidia-utils
|
||||
pkgname=('nvidia-utils')
|
||||
pkgver=615.71.09
|
||||
pkgrel=1.1
|
||||
arch=('aarch64')
|
||||
url="https://www.nvidia.com/"
|
||||
license=('LicenseRef-NVIDIA-Driver-License-Agreement')
|
||||
options=('!strip')
|
||||
source_aarch64=("https://download.nvidia.com/XFree86/Linux-aarch64/${pkgver}/NVIDIA-Linux-aarch64-${pkgver}.run")
|
||||
source=('nvidia-drm-outputclass.conf'
|
||||
'nvidia-utils.sysusers'
|
||||
'nvidia.rules'
|
||||
'systemd-homed-override.conf'
|
||||
'systemd-suspend-override.conf'
|
||||
'nvidia-utils.conf')
|
||||
sha512sums=('de7116c09f282a27920a1382df84aa86f559e537664bb30689605177ce37dc5067748acf9afd66a3269a6e323461356592fdfc624c86523bf105ff8fe47d3770'
|
||||
'1bcf2c6ee71686c0d32625e746ec8c0f7cf42fc63c76c3076ff2526b2661e8b9e9f76eaa2c4b213c7cc437a6f06006cc07672c4974d7f4515b2de2fd7c47a891'
|
||||
'7f1457dc454144fdece5abf795744c4c948a13feb8d49c20e2a1b8b8973e86f980233b521485d73eb039c396688f287a3a5b3de8cb1fb20ed70cc62e4ba91250'
|
||||
'a0183adce78e40853edf7e6b73867e7a8ea5dabac8e8164e42781f64d5232fbe869f850ab0697c3718ebced5cde760d0e807c05da50a982071dfe1157c31d6b8'
|
||||
'55def6319f6abb1a4ccd28a89cd60f1933d155c10ba775b8dfa60a2dc5696b4b472c14b252dc0891f956e70264be87c3d5d4271e929a4fc4b1a68a6902814cee'
|
||||
'a380e5faeb19293c90f613cd92bcd1cef7597ee52f79f03ffdffe5d37d2badc05b6bdb4c26a9d610868ae4c16eafd56e7d16f769e849dc0335d0d248c6235fe9')
|
||||
sha512sums_aarch64=('316f90d5e0ba74db3a79a91464955240aa2c14e986653067fe902c132c771898d2866afc4e6498069b33665596e17b1b5282980936e1e6e31cabb53787e70196')
|
||||
|
||||
_pkg=NVIDIA-Linux-${CARCH}-${pkgver}
|
||||
|
||||
create_links() {
|
||||
# create soname links
|
||||
find "$pkgdir" -type f -name '*.so*' ! -path '*xorg/*' -print0 | while read -d $'\0' _lib; do
|
||||
_soname=$(dirname "${_lib}")/$(readelf -d "${_lib}" | grep -Po 'SONAME.*: \[\K[^]]*' || true)
|
||||
_base=$(echo ${_soname} | sed -r 's/(.*)\.so.*/\1.so/')
|
||||
[[ -e "${_soname}" ]] || ln -s $(basename "${_lib}") "${_soname}"
|
||||
[[ -e "${_base}" ]] || ln -s $(basename "${_soname}") "${_base}"
|
||||
done
|
||||
}
|
||||
|
||||
prepare() {
|
||||
sh ${_pkg}.run --extract-only
|
||||
cd ${_pkg}
|
||||
bsdtar -xf nvidia-persistenced-init.tar.bz2
|
||||
|
||||
}
|
||||
|
||||
package_nvidia-utils() {
|
||||
pkgdesc="NVIDIA drivers utilities"
|
||||
depends=('libglvnd' 'egl-wayland' 'egl-wayland2' 'egl-gbm' 'egl-x11')
|
||||
optdepends=('nvidia-settings: configuration tool'
|
||||
'xorg-server: Xorg support'
|
||||
'xorg-server-devel: nvidia-xconfig'
|
||||
'opencl-nvidia: OpenCL support')
|
||||
conflicts=('nvidia-libgl')
|
||||
provides=('vulkan-driver' 'opengl-driver' 'nvidia-libgl')
|
||||
replaces=('nvidia-libgl')
|
||||
install="${pkgname}.install"
|
||||
|
||||
cd "${_pkg}"
|
||||
|
||||
# Check http://us.download.nvidia.com/XFree86/Linux-x86_64/${pkgver}/README/installedcomponents.html
|
||||
# for hints on what needs to be installed where.
|
||||
|
||||
# X driver
|
||||
install -Dm755 nvidia_drv.so "${pkgdir}/usr/lib/xorg/modules/drivers/nvidia_drv.so"
|
||||
|
||||
# Wayland/GBM
|
||||
mkdir -p "${pkgdir}/usr/lib/gbm"
|
||||
ln -sr "${pkgdir}/usr/lib/libnvidia-allocator.so.${pkgver}" "${pkgdir}/usr/lib/gbm/nvidia-drm_gbm.so"
|
||||
|
||||
# firmware
|
||||
install -Dm644 -t "${pkgdir}/usr/lib/firmware/nvidia/${pkgver}/" firmware/*.bin
|
||||
|
||||
# GLX extension module for X
|
||||
install -Dm755 "libglxserver_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so.${pkgver}"
|
||||
# Ensure that X finds glx
|
||||
ln -s "libglxserver_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so.1"
|
||||
ln -s "libglxserver_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/nvidia/xorg/libglxserver_nvidia.so"
|
||||
|
||||
install -Dm755 "libGLX_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/libGLX_nvidia.so.${pkgver}"
|
||||
|
||||
# OpenGL libraries
|
||||
install -Dm755 "libEGL_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/libEGL_nvidia.so.${pkgver}"
|
||||
install -Dm755 "libGLESv1_CM_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/libGLESv1_CM_nvidia.so.${pkgver}"
|
||||
install -Dm755 "libGLESv2_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/libGLESv2_nvidia.so.${pkgver}"
|
||||
install -Dm644 "10_nvidia.json" "${pkgdir}/usr/share/glvnd/egl_vendor.d/10_nvidia.json"
|
||||
|
||||
# OpenGL core library
|
||||
install -Dm755 "libnvidia-glcore.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-glcore.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-eglcore.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-eglcore.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-glsi.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-glsi.so.${pkgver}"
|
||||
if [[ $CARCH == aarch64 ]]; then
|
||||
# Required by the ARM EGL/GLX libraries.
|
||||
install -Dm755 "libnvidia-rmapi-tegra.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-rmapi-tegra.so.${pkgver}"
|
||||
fi
|
||||
|
||||
# misc
|
||||
install -Dm755 "libnvidia-api.so.1" "${pkgdir}/usr/lib/libnvidia-api.so.1"
|
||||
install -Dm755 "libnvidia-fbc.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-fbc.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-encode.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-encode.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-cfg.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-cfg.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-ml.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-ml.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-fmdrv.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-fmdrv.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-imex.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-imex.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-glvkspirv.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-glvkspirv.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-allocator.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-allocator.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-gpucomp.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-gpucomp.so.${pkgver}"
|
||||
|
||||
# Vulkan ICD
|
||||
install -Dm644 "nvidia_icd.json" "${pkgdir}/usr/share/vulkan/icd.d/nvidia_icd.json"
|
||||
install -Dm644 "nvidia_layers.json" "${pkgdir}/usr/share/vulkan/implicit_layer.d/nvidia_layers.json"
|
||||
|
||||
if [[ $CARCH = x86_64 ]]; then
|
||||
# VulkanSC
|
||||
install -D -m755 nvidia-pcc -t "${pkgdir}/usr/bin"
|
||||
install -D -m755 "libnvidia-vksc-core.so.${pkgver}" -t "${pkgdir}/usr/lib"
|
||||
install -D -m644 nvidia_icd_vksc.json -t "${pkgdir}/usr/share/vulkansc/icd.d"
|
||||
fi
|
||||
|
||||
# VDPAU
|
||||
install -Dm755 "libvdpau_nvidia.so.${pkgver}" "${pkgdir}/usr/lib/vdpau/libvdpau_nvidia.so.${pkgver}"
|
||||
|
||||
# nvidia-tls library
|
||||
install -Dm755 "libnvidia-tls.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-tls.so.${pkgver}"
|
||||
|
||||
# CUDA
|
||||
install -Dm755 "libcuda.so.${pkgver}" "${pkgdir}/usr/lib/libcuda.so.${pkgver}"
|
||||
install -Dm755 "libnvcuvid.so.${pkgver}" "${pkgdir}/usr/lib/libnvcuvid.so.${pkgver}"
|
||||
install -Dm755 "libcudadebugger.so.${pkgver}" "${pkgdir}/usr/lib/libcudadebugger.so.${pkgver}"
|
||||
|
||||
# NVVM Compiler library loaded by the CUDA driver to do JIT link-time-optimization
|
||||
install -Dm644 "libnvidia-nvvm.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-nvvm.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-nvvm70.so.4" "${pkgdir}/usr/lib/libnvidia-nvvm70.so.4"
|
||||
|
||||
# PTX JIT Compiler (Parallel Thread Execution (PTX) is a pseudo-assembly language for CUDA)
|
||||
install -Dm755 "libnvidia-ptxjitcompiler.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-ptxjitcompiler.so.${pkgver}"
|
||||
|
||||
# raytracing
|
||||
install -Dm755 "nvoptix.bin" "${pkgdir}/usr/share/nvidia/nvoptix.bin"
|
||||
install -Dm755 "libnvoptix.so.${pkgver}" "${pkgdir}/usr/lib/libnvoptix.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-rtcore.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-rtcore.so.${pkgver}"
|
||||
|
||||
# NGX
|
||||
install -Dm755 nvidia-ngx-updater "${pkgdir}/usr/bin/nvidia-ngx-updater"
|
||||
install -Dm755 "libnvidia-ngx.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-ngx.so.${pkgver}"
|
||||
if [[ $CARCH = x86_64 ]]; then
|
||||
install -Dm755 _nvngx.dll "${pkgdir}/usr/lib/nvidia/wine/_nvngx.dll"
|
||||
install -Dm755 nvngx.dll "${pkgdir}/usr/lib/nvidia/wine/nvngx.dll"
|
||||
install -Dm755 nvngx_dlssg.dll "${pkgdir}/usr/lib/nvidia/wine/nvngx_dlssg.dll"
|
||||
fi
|
||||
|
||||
# Optical flow
|
||||
install -Dm755 "libnvidia-opticalflow.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-opticalflow.so.${pkgver}"
|
||||
|
||||
if [[ $CARCH = x86_64 ]]; then
|
||||
# Cryptography library wrapper
|
||||
install -Dm755 "libnvidia-pkcs11.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-pkcs11.so.${pkgver}"
|
||||
install -Dm755 "libnvidia-pkcs11-openssl3.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-pkcs11-openssl3.so.${pkgver}"
|
||||
fi
|
||||
|
||||
# Sandboxhelper
|
||||
install -Dm755 "libnvidia-sandboxutils.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-sandboxutils.so.${pkgver}"
|
||||
|
||||
# Present Helper
|
||||
install -Dm755 "libnvidia-present.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-present.so.${pkgver}"
|
||||
|
||||
# https://github.com/microsoft/TileIR
|
||||
install -Dm755 "libnvidia-tileiras.so.${pkgver}" "${pkgdir}/usr/lib/libnvidia-tileiras.so.${pkgver}"
|
||||
|
||||
# Debug
|
||||
install -Dm755 nvidia-debugdump "${pkgdir}/usr/bin/nvidia-debugdump"
|
||||
|
||||
# nvidia-xconfig
|
||||
install -Dm755 nvidia-xconfig "${pkgdir}/usr/bin/nvidia-xconfig"
|
||||
install -Dm644 nvidia-xconfig.1.gz "${pkgdir}/usr/share/man/man1/nvidia-xconfig.1.gz"
|
||||
|
||||
# nvidia-bug-report
|
||||
install -Dm755 nvidia-bug-report.sh "${pkgdir}/usr/bin/nvidia-bug-report.sh"
|
||||
|
||||
# nvidia-smi
|
||||
install -Dm755 nvidia-smi "${pkgdir}/usr/bin/nvidia-smi"
|
||||
install -Dm644 nvidia-smi.1.gz "${pkgdir}/usr/share/man/man1/nvidia-smi.1.gz"
|
||||
|
||||
# nvidia-cuda-mps
|
||||
install -Dm755 nvidia-cuda-mps-server "${pkgdir}/usr/bin/nvidia-cuda-mps-server"
|
||||
install -Dm755 nvidia-cuda-mps-control "${pkgdir}/usr/bin/nvidia-cuda-mps-control"
|
||||
install -Dm644 nvidia-cuda-mps-control.1.gz "${pkgdir}/usr/share/man/man1/nvidia-cuda-mps-control.1.gz"
|
||||
|
||||
# nvidia-modprobe
|
||||
# This should be removed if nvidia fixed their uvm module!
|
||||
install -Dm4755 nvidia-modprobe "${pkgdir}/usr/bin/nvidia-modprobe"
|
||||
install -Dm644 nvidia-modprobe.1.gz "${pkgdir}/usr/share/man/man1/nvidia-modprobe.1.gz"
|
||||
|
||||
# nvidia-persistenced
|
||||
install -Dm755 nvidia-persistenced "${pkgdir}/usr/bin/nvidia-persistenced"
|
||||
install -Dm644 nvidia-persistenced.1.gz "${pkgdir}/usr/share/man/man1/nvidia-persistenced.1.gz"
|
||||
install -Dm644 nvidia-persistenced-init/systemd/nvidia-persistenced.service.template "${pkgdir}/usr/lib/systemd/system/nvidia-persistenced.service"
|
||||
sed -i 's/__USER__/nvidia-persistenced/' "${pkgdir}/usr/lib/systemd/system/nvidia-persistenced.service"
|
||||
|
||||
# application profiles
|
||||
install -Dm644 "nvidia-application-profiles-${pkgver}-rc" "${pkgdir}/usr/share/nvidia/nvidia-application-profiles-${pkgver}-rc"
|
||||
install -Dm644 "nvidia-application-profiles-${pkgver}-key-documentation" "${pkgdir}/usr/share/nvidia/nvidia-application-profiles-${pkgver}-key-documentation"
|
||||
|
||||
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/nvidia-utils/LICENSE"
|
||||
install -Dm644 README.txt "${pkgdir}/usr/share/doc/nvidia/README"
|
||||
install -Dm644 NVIDIA_Changelog "${pkgdir}/usr/share/doc/nvidia/NVIDIA_Changelog"
|
||||
cp -r html "${pkgdir}/usr/share/doc/nvidia/"
|
||||
ln -s nvidia "${pkgdir}/usr/share/doc/nvidia-utils"
|
||||
|
||||
# new power management support
|
||||
install -Dm644 systemd/system/*.service -t "${pkgdir}/usr/lib/systemd/system"
|
||||
install -Dm755 systemd/system-sleep/nvidia "${pkgdir}/usr/lib/systemd/system-sleep/nvidia"
|
||||
install -Dm755 systemd/nvidia-sleep.sh "${pkgdir}/usr/bin/nvidia-sleep.sh"
|
||||
install -Dm755 nvidia-powerd "${pkgdir}/usr/bin/nvidia-powerd"
|
||||
install -Dm644 dlsnetparams.csv "${pkgdir}/usr/share/nvidia/nvidia-powerd/dlsnetparams.csv"
|
||||
install -Dm644 nvidia-dbus.conf "${pkgdir}/usr/share/dbus-1/system.d/nvidia-dbus.conf"
|
||||
install -Dm644 "${srcdir}/systemd-homed-override.conf" "${pkgdir}/usr/lib/systemd/system/systemd-homed.service.d/10-nvidia-no-freeze-session.conf"
|
||||
install -Dm644 "${srcdir}/systemd-suspend-override.conf" "${pkgdir}/usr/lib/systemd/system/systemd-suspend.service.d/10-nvidia-no-freeze-session.conf"
|
||||
install -Dm644 "${srcdir}/systemd-suspend-override.conf" "${pkgdir}/usr/lib/systemd/system/systemd-suspend-then-hibernate.service.d/10-nvidia-no-freeze-session.conf"
|
||||
install -Dm644 "${srcdir}/systemd-suspend-override.conf" "${pkgdir}/usr/lib/systemd/system/systemd-hibernate.service.d/10-nvidia-no-freeze-session.conf"
|
||||
install -Dm644 "${srcdir}/systemd-suspend-override.conf" "${pkgdir}/usr/lib/systemd/system/systemd-hybrid-sleep.service.d/10-nvidia-no-freeze-session.conf"
|
||||
|
||||
# distro specific files must be installed in /usr/share/X11/xorg.conf.d
|
||||
install -Dm644 "${srcdir}/nvidia-drm-outputclass.conf" "${pkgdir}/usr/share/X11/xorg.conf.d/10-nvidia-drm-outputclass.conf"
|
||||
|
||||
install -Dm644 "${srcdir}/nvidia-utils.sysusers" "${pkgdir}/usr/lib/sysusers.d/$pkgname.conf"
|
||||
|
||||
install -Dm644 "${srcdir}/nvidia.rules" "$pkgdir"/usr/lib/udev/rules.d/60-nvidia.rules
|
||||
|
||||
# Enable kernel suspend notifiers for open modules and override TemporaryFilePath
|
||||
# from default /tmp to /var/tmp
|
||||
install -Dm644 "${srcdir}/nvidia-utils.conf" "${pkgdir}/usr/lib/modprobe.d/nvidia-utils.conf"
|
||||
|
||||
# Lists NVIDIA driver files for container runtimes like nvidia-container-toolkit
|
||||
install -Dm644 sandboxutils-filelist.json "${pkgdir}/usr/share/nvidia/files.d/sandboxutils-filelist.json"
|
||||
|
||||
create_links
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Temporary NVIDIA ARM packaging correction
|
||||
|
||||
Carries Arch Linux's `nvidia-utils` recipe at
|
||||
[f9ae10b379f8b1d0832ec92bca1c12072aa123e9](https://gitlab.archlinux.org/archlinux/packaging/packages/nvidia-utils/-/commit/f9ae10b379f8b1d0832ec92bca1c12072aa123e9),
|
||||
restricted to aarch64 and the nvidia-utils output. Upstream contributor credits,
|
||||
packaging license and support files are retained. The OpenCL/DKMS split outputs
|
||||
and their unused kernel source preparation are omitted.
|
||||
|
||||
NVIDIA 615.71.09's ARM EGL/GLX libraries require
|
||||
`libnvidia-rmapi-tegra.so.615.71.09`. NVIDIA includes it in its archive, but the
|
||||
Arch recipe omits it. Adding that library and its generated symlink fixes
|
||||
Hyprland's EGL initialization failure on DGX Spark. No rendering overrides are
|
||||
installed. The correction passed package installation, normal desktop login
|
||||
and reboot on a Spark running kernel 7.2.6 with NVIDIA 615.71.09.
|
||||
|
||||
This recipe builds only for edge, using release 1.1 to sit above Arch's broken
|
||||
release 1 and below a prospective fixed release 2. There is deliberately no
|
||||
automatic NVIDIA version watcher: driver userspace must remain compatible with
|
||||
the kernel package supplied by Arch Linux ARM. Check both packages before each
|
||||
release; a stale overlay must not hold back a driver transition.
|
||||
|
||||
## Delivery and removal
|
||||
|
||||
Publishing requires an aarch64 edge build. Consumers must put `[omarchy]`
|
||||
before `[extra]` in pacman.conf for unqualified installation and updates to
|
||||
select this package. A higher pkgrel alone does not overcome repository order.
|
||||
The tested Spark has that ordering; this PR does not change shared runtime or
|
||||
installer configuration. Deployment must verify that ordering on the intended
|
||||
ARM installation/update paths. This is not a claim of fresh-ISO validation.
|
||||
|
||||
The upstream Arch submission is pending account approval. Once Arch Linux ARM
|
||||
ships the missing library, validate that package on the Spark, remove this
|
||||
recipe AND the published overlay package/database entry, and verify that normal
|
||||
updates select the fixed Arch package. A higher Arch version alone does not
|
||||
bypass an earlier repository's stale package. Do not use an epoch or rename the
|
||||
package to prevent that transition.
|
||||
@@ -0,0 +1,8 @@
|
||||
Section "OutputClass"
|
||||
Identifier "nvidia"
|
||||
MatchDriver "nvidia-drm"
|
||||
Driver "nvidia"
|
||||
Option "AllowEmptyInitialConfiguration"
|
||||
ModulePath "/usr/lib/nvidia/xorg"
|
||||
ModulePath "/usr/lib/xorg/modules"
|
||||
EndSection
|
||||
@@ -0,0 +1,15 @@
|
||||
# Blacklist nouveau and nova
|
||||
blacklist nouveau
|
||||
blacklist nova_core
|
||||
blacklist nova_drm
|
||||
|
||||
# Make sure that all modules are loaded after the main one.
|
||||
softdep nvidia post: nvidia-uvm nvidia-drm
|
||||
|
||||
# https://download.nvidia.com/XFree86/Linux-x86_64/595.45.04/README/powermanagement.html
|
||||
# Enable Suspend Notifiers for faster and more modern suspend
|
||||
options nvidia NVreg_UseKernelSuspendNotifiers=1
|
||||
#
|
||||
# The destination should not be using tmpfs, so we prefer
|
||||
# /var/tmp instead of /tmp
|
||||
options nvidia NVreg_TemporaryFilePath=/var/tmp
|
||||
@@ -0,0 +1,21 @@
|
||||
post_upgrade() {
|
||||
# With 595+ open kernel modules, video memory preservation is handled by
|
||||
# kernel suspend notifiers, making the nvidia suspend/hibernate services unnecessary.
|
||||
# Disable them for users upgrading from older versions.
|
||||
if (( $(vercmp $2 595.58.03-1) < 0)); then
|
||||
for service in nvidia-resume nvidia-hibernate nvidia-suspend nvidia-suspend-then-hibernate; do
|
||||
if systemctl is-enabled --quiet $service 2>/dev/null; then
|
||||
echo "Disabling $service (no longer needed with open kernel modules)..."
|
||||
systemctl disable $service
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
pre_remove() {
|
||||
for service in nvidia-resume nvidia-hibernate nvidia-suspend nvidia-suspend-then-hibernate; do
|
||||
if systemctl is-enabled --quiet $service 2>/dev/null; then
|
||||
systemctl disable $service
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
u! nvidia-persistenced 143 'NVIDIA Persistence Daemon'
|
||||
@@ -0,0 +1,7 @@
|
||||
# Device nodes are created by nvidia-modprobe, which is called by the nvidia DDX.
|
||||
# In case the DDX is not started, the device nodes are never created, so call
|
||||
# nvidia-modprobe in the udev rules to cover the Wayland/EGLStream and compute
|
||||
# case without a started display. In the case where vfio-pci is used
|
||||
# nvidia-modprobe should not be invoked.
|
||||
ACTION=="add", SUBSYSTEM=="module", KERNEL=="nvidia_drm", TEST!="/dev/nvidia-uvm", \
|
||||
RUN+="/usr/bin/nvidia-modprobe -c0 -u"
|
||||
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
Environment="SYSTEMD_HOME_LOCK_FREEZE_SESSION=false"
|
||||
@@ -0,0 +1,2 @@
|
||||
[Service]
|
||||
Environment="SYSTEMD_SLEEP_FREEZE_USER_SESSIONS=false"
|
||||
@@ -1,5 +1,5 @@
|
||||
pkgname=omakade
|
||||
pkgver=1.9.2
|
||||
pkgver=1.10.0
|
||||
pkgrel=1
|
||||
pkgdesc='A beautiful, local-first game library for Omarchy'
|
||||
arch=('x86_64' 'aarch64')
|
||||
@@ -11,7 +11,7 @@ depends=('glib2' 'hicolor-icon-theme' 'libsecret' 'libzip' 'openssl' 'qt6-base'
|
||||
makedepends=('cmake' 'ninja' 'pkgconf' 'wayland-protocols')
|
||||
options=('!debug')
|
||||
source=("$pkgname-$pkgver.tar.gz::https://github.com/btsouth/omakade/releases/download/v$pkgver/$pkgname-$pkgver.tar.gz")
|
||||
sha256sums=('4c0ba7eecc036b959b34a8068f5923e8927e59b8ee2f0398d470cd933343c4fc')
|
||||
sha256sums=('01a4c1aa35c51aba54f57fd0d4eab4a00a14ca2bd4d1b6163264b8ba6fed5b55')
|
||||
|
||||
build() {
|
||||
cmake -S "$pkgname-$pkgver" -B build -G Ninja \
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"source": "local",
|
||||
"release_ring": "fast",
|
||||
"min_release_age": "24h",
|
||||
"upstream": {
|
||||
"github": "llstrk/omarchy-billboard-generator",
|
||||
"checksums": "SHA256SUMS",
|
||||
"assets": {
|
||||
"any": "omarchy-billboard-generator.tar.gz"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
# Maintainer: David Heinemeier Hansson <david@hey.com>
|
||||
|
||||
# Upstream ships a release archive plus a SHA256SUMS manifest, which is what
|
||||
# the upstream feed in .omarchy/package.json follows. Chromium and ffmpeg are
|
||||
# runtime dependencies found on PATH, never downloaded.
|
||||
|
||||
pkgname=omarchy-billboard-generator
|
||||
pkgver=0.2.0
|
||||
pkgrel=1
|
||||
pkgdesc='Desktop app and CLI that renders animated OMARCHY domain videos'
|
||||
arch=('any')
|
||||
url='https://github.com/llstrk/omarchy-billboard-generator'
|
||||
# MIT covers the project's own code and Apache-2.0 and 0BSD the vendored npm
|
||||
# dependencies. The Omarchy wordmark, website palettes, taglines and the ttfx
|
||||
# animation runtime are Omarchy's own material carried over from omarchy-site,
|
||||
# and PROVENANCE.md says which file is which.
|
||||
license=('MIT' 'Apache-2.0' '0BSD' 'OFL-1.1' 'LicenseRef-Omarchy')
|
||||
depends=('nodejs>=22' 'chromium' 'ffmpeg' 'xdg-utils')
|
||||
makedepends=('npm')
|
||||
source=("${pkgname}-${pkgver}.tar.gz::${url}/releases/download/v${pkgver}/${pkgname}.tar.gz")
|
||||
sha256sums=('f499dfc1201ed3d6b8fba271496fcd4c8fc6301427f4f2fc53aab8d9c3f64f67')
|
||||
# Pure JavaScript and WebAssembly; nothing here is an ELF to strip.
|
||||
options=('!strip' '!debug')
|
||||
|
||||
_appdir="/usr/lib/${pkgname}"
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${pkgname}"
|
||||
# The same install the upstream release installer performs: locked production
|
||||
# dependencies, no lifecycle scripts.
|
||||
npm ci --omit=dev --ignore-scripts --cache "${srcdir}/npm-cache"
|
||||
}
|
||||
|
||||
check() {
|
||||
cd "${srcdir}/${pkgname}"
|
||||
# The catalogs prefer a synced snapshot in the user data directory, so point
|
||||
# them at an empty one: the build must read the bundled data, not whatever
|
||||
# the builder's home happens to hold.
|
||||
export BILLBOARD_DATA_DIR="${srcdir}/data-home" BILLBOARD_CACHE_DIR="${srcdir}/cache-home"
|
||||
# Upstream's own startup check, plus the catalogs that load the bundled data.
|
||||
node bin/omarchy-billboard --help >/dev/null
|
||||
node bin/omarchy-billboard --list-themes >/dev/null
|
||||
node bin/omarchy-billboard --list-languages >/dev/null
|
||||
node bin/omarchy-billboard --list-animations >/dev/null
|
||||
node bin/omarchy-billboard-app --help >/dev/null
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${pkgname}"
|
||||
|
||||
install -dm755 "${pkgdir}${_appdir}"
|
||||
# Only what runs: no tests, release scripts, CI, or the curl|bash installer.
|
||||
cp -a bin src app web assets data examples node_modules package.json "${pkgdir}${_appdir}/"
|
||||
|
||||
# The entry points resolve their sources through the real path of the
|
||||
# script, so a symlink is enough and keeps the launcher's node on PATH.
|
||||
install -dm755 "${pkgdir}/usr/bin"
|
||||
ln -s "${_appdir}/bin/omarchy-billboard" "${pkgdir}/usr/bin/omarchy-billboard"
|
||||
ln -s "${_appdir}/bin/omarchy-billboard-app" "${pkgdir}/usr/bin/omarchy-billboard-app"
|
||||
|
||||
# Written here rather than shipped as a second source: sync-upstream rewrites
|
||||
# sha256sums wholesale from the release manifest, so a local file's checksum
|
||||
# would not survive the first version bump. The WM class is what Chromium
|
||||
# derives for this app-mode window, so the launcher's icon follows it.
|
||||
install -dm755 "${pkgdir}/usr/share/applications"
|
||||
cat > "${pkgdir}/usr/share/applications/${pkgname}.desktop" <<'DESKTOP'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Omarchy Billboard Generator
|
||||
Comment=Create animated Omarchy domain videos locally
|
||||
Exec=omarchy-billboard-app
|
||||
Icon=omarchy-billboard-generator
|
||||
Terminal=false
|
||||
Categories=AudioVideo;Video;
|
||||
StartupWMClass=chrome-127.0.0.1__omarchy-billboard-Default
|
||||
DESKTOP
|
||||
install -Dm644 app/icon.svg "${pkgdir}/usr/share/icons/hicolor/scalable/apps/${pkgname}.svg"
|
||||
|
||||
install -Dm644 -t "${pkgdir}/usr/share/doc/${pkgname}" README.md THEMES.md PROVENANCE.md
|
||||
install -Dm644 -t "${pkgdir}/usr/share/licenses/${pkgname}" LICENSE PROVENANCE.md assets/fonts/*-OFL.txt
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# Maintainer: Ryan Hughes <ryan@omarchy.org>
|
||||
pkgname=omarchy-nvim
|
||||
pkgver=2026.8.13
|
||||
pkgver=2026.9.21
|
||||
pkgrel=1
|
||||
pkgdesc="Pre-built LazyVim configuration with cached plugins"
|
||||
arch=('any')
|
||||
|
||||
@@ -77,7 +77,7 @@ return {
|
||||
priority = 1000,
|
||||
},
|
||||
{
|
||||
"gthelding/monokai-pro.nvim",
|
||||
"loctvl842/monokai-pro.nvim",
|
||||
lazy = true,
|
||||
priority = 1000,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"source": "local"
|
||||
}
|
||||
Loaded 100 of 145 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user