Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4cc32340c | ||
|
|
44d4d231be | ||
|
|
7000c95661 | ||
|
|
5c6444e604 | ||
|
|
17ae27fb21 | ||
|
|
5abe08fbab | ||
|
|
3a0d01876f | ||
|
|
0aa4c721c1 | ||
|
|
c71cfabed6 | ||
|
|
7d18e16925 | ||
|
|
2cce621d95 | ||
|
|
2ac2319b55 | ||
|
|
cb3909f052 | ||
|
|
678d7400ed | ||
|
|
ebd2d6a766 | ||
|
|
93b1655ca8 | ||
|
|
5d9783b85e | ||
|
|
48d6217ff7 | ||
|
|
7d2c7c50af | ||
|
|
e285432795 | ||
|
|
5961a3ff5d | ||
|
|
259a3fa8b8 | ||
|
|
37288aada4 | ||
|
|
128c5647ba | ||
|
|
024943141d | ||
|
|
a1ad25bbae | ||
|
|
77d62dd156 | ||
|
|
7d70768c3f | ||
|
|
efc09808c6 | ||
|
|
f004f5fa20 | ||
|
|
963cbf1230 | ||
|
|
a57d0fdb7f | ||
|
|
00a98d2aa7 | ||
|
|
d37fcd09d1 | ||
|
|
c19b48c445 | ||
|
|
0e90a7652b | ||
|
|
4b6cc8ba0f | ||
|
|
2d56129a55 | ||
|
|
fe4b80b0a6 | ||
|
|
a84ad64c9e | ||
|
|
5e0ff0df95 |
No files matched your search
@@ -0,0 +1,84 @@
|
|||||||
|
// Whether a PR rides to master on its own once the required checks pass.
|
||||||
|
//
|
||||||
|
// The rule is the build gate's, from build-pr.yml: a PR trusted to build is
|
||||||
|
// trusted to ship. Collaborators, vouched authors and bots are trusted; an
|
||||||
|
// unknown author is trusted while the PR carries build-approved; a
|
||||||
|
// denouncement is absolute. Two limits on top of it:
|
||||||
|
//
|
||||||
|
// - Only package changes. A PR's workflows, scripts and build tooling never
|
||||||
|
// run in its own build (build-pr.yml overlays only its package directories
|
||||||
|
// onto base tooling), so green checks say nothing about them, and after
|
||||||
|
// merge they run with the publish secrets. Allowed: anything under
|
||||||
|
// pkgbuilds/, plus the test a package PR brings with it, which is a new
|
||||||
|
// file under tests/ and lines in test.yml that only run new tests/*.sh.
|
||||||
|
// test.yml runs on PRs only; an existing test may also run on master
|
||||||
|
// (builder-images.yml runs tests/build-isolation.sh with packages: write),
|
||||||
|
// so editing one still needs a maintainer.
|
||||||
|
// - Not the upstream sync. It labels its own PR build-approved to release
|
||||||
|
// GitHub's hold on its pushes, which is no one's approval; it stays on the
|
||||||
|
// reviewed lane.
|
||||||
|
const PACKAGES = 'pkgbuilds/';
|
||||||
|
const TESTS = 'tests/';
|
||||||
|
const TEST_WORKFLOW = '.github/workflows/test.yml';
|
||||||
|
const TEST_LINE = /^\+\s*\.\/tests\/[A-Za-z0-9._-]+\.sh\s*$/;
|
||||||
|
|
||||||
|
// Every changed line adds a ./tests/<name>.sh call; nothing removed. A diff
|
||||||
|
// too large for the API has no patch and does not qualify.
|
||||||
|
function onlyRunsTests(patch) {
|
||||||
|
if (!patch) return false;
|
||||||
|
const changed = patch.split('\n').filter(line =>
|
||||||
|
/^[+-]/.test(line) && !line.startsWith('+++') && !line.startsWith('---'));
|
||||||
|
return changed.length > 0 && changed.every(line => TEST_LINE.test(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
function packageChange(file) {
|
||||||
|
if (file.previous_filename && !file.previous_filename.startsWith(PACKAGES)) return false;
|
||||||
|
if (file.filename.startsWith(PACKAGES)) return true;
|
||||||
|
if (file.filename.startsWith(TESTS)) return file.status === 'added';
|
||||||
|
if (file.filename === TEST_WORKFLOW) return file.status === 'modified' && onlyRunsTests(file.patch);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const REVIEWED_BRANCHES = /^auto\/sync-upstream(\/|$)/;
|
||||||
|
|
||||||
|
function decide({ pr, files, vouchStatus, repository }) {
|
||||||
|
if (pr.state !== 'open') return { enable: false, reason: 'PR is not open' };
|
||||||
|
if (pr.draft) return { enable: false, reason: 'PR is a draft' };
|
||||||
|
|
||||||
|
const labelled = pr.labels.some(label => label.name === 'build-approved');
|
||||||
|
let trusted;
|
||||||
|
switch (vouchStatus) {
|
||||||
|
case 'bot': case 'collaborator': case 'vouched': trusted = true; break;
|
||||||
|
case 'unknown': trusted = labelled; break;
|
||||||
|
default: trusted = false; // denounced, or a failed lookup
|
||||||
|
}
|
||||||
|
if (!trusted) {
|
||||||
|
return { enable: false, reason: `author not trusted to build (${vouchStatus || 'missing'}${labelled ? ', labelled' : ''})` };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pr.head.repo?.full_name === repository && REVIEWED_BRANCHES.test(pr.head.ref)) {
|
||||||
|
return { enable: false, reason: `${pr.head.ref} stays on the reviewed lane` };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!files.length) return { enable: false, reason: 'PR changes no files' };
|
||||||
|
const outside = files.filter(file => !packageChange(file));
|
||||||
|
if (outside.length) {
|
||||||
|
const names = outside.slice(0, 3).map(file => file.filename).join(', ');
|
||||||
|
return { enable: false, reason: `changes more than packages and their new tests: ${names}${outside.length > 3 ? ', ...' : ''}` };
|
||||||
|
}
|
||||||
|
return { enable: true, reason: `${vouchStatus === 'unknown' ? 'build-approved' : vouchStatus} author, package changes only` };
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = async function autoMerge({ github, context, core, number, vouchStatus }) {
|
||||||
|
const { data: pr } = await github.rest.pulls.get({ ...context.repo, pull_number: number });
|
||||||
|
const files = await github.paginate(github.rest.pulls.listFiles, {
|
||||||
|
...context.repo, pull_number: number, per_page: 100,
|
||||||
|
});
|
||||||
|
const decision = decide({
|
||||||
|
pr, files, vouchStatus, repository: `${context.repo.owner}/${context.repo.repo}`,
|
||||||
|
});
|
||||||
|
core.info(`#${number}: ${decision.enable ? 'auto-merge' : 'leave for a maintainer'} (${decision.reason})`);
|
||||||
|
core.setOutput('enable', String(decision.enable));
|
||||||
|
core.setOutput('head_sha', pr.head.sha);
|
||||||
|
return decision;
|
||||||
|
};
|
||||||
|
module.exports.decide = decide;
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
name: Auto-merge approved package PRs
|
||||||
|
|
||||||
|
# A package PR trusted to build is trusted to ship: once its builds are
|
||||||
|
# green it should merge and publish without a maintainer pressing the
|
||||||
|
# button. This enables GitHub's auto-merge on such PRs; branch protection
|
||||||
|
# still holds the merge until `result`, `self-tests` and `build-isolation`
|
||||||
|
# pass, and a red build stays an open PR. .github/scripts/auto-merge-pr.cjs
|
||||||
|
# has the rule.
|
||||||
|
#
|
||||||
|
# Auto-merge is enabled with the PAT in PKGS_BOT_TOKEN: a merge made with the
|
||||||
|
# built-in GITHUB_TOKEN does not start publish.yml.
|
||||||
|
#
|
||||||
|
# pull_request_target runs this default-branch code with secrets; the PR's
|
||||||
|
# code is never checked out here.
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, reopened, synchronize, ready_for_review, labeled, unlabeled]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pr:
|
||||||
|
description: 'PR number to evaluate'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: auto-merge-pr-${{ github.event.pull_request.number || github.event.inputs.pr }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
auto-merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.repository.default_branch }}
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Find the PR's author
|
||||||
|
id: pr
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
env:
|
||||||
|
NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr }}
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { data: pr } = await github.rest.pulls.get({
|
||||||
|
...context.repo, pull_number: Number(process.env.NUMBER),
|
||||||
|
});
|
||||||
|
core.setOutput('number', String(pr.number));
|
||||||
|
core.setOutput('author', pr.user.login);
|
||||||
|
|
||||||
|
- id: vouch
|
||||||
|
uses: mitchellh/vouch/action/check-user@f23dbb5e745334f97414ec70463ce7301071a661 # v1
|
||||||
|
with:
|
||||||
|
user: ${{ steps.pr.outputs.author }}
|
||||||
|
allow-fail: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Decide
|
||||||
|
id: decide
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
env:
|
||||||
|
NUMBER: ${{ steps.pr.outputs.number }}
|
||||||
|
VOUCH_STATUS: ${{ steps.vouch.outputs.status }}
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const autoMerge = require('./.github/scripts/auto-merge-pr.cjs');
|
||||||
|
await autoMerge({ github, context, core,
|
||||||
|
number: Number(process.env.NUMBER), vouchStatus: process.env.VOUCH_STATUS });
|
||||||
|
|
||||||
|
- name: Enable auto-merge
|
||||||
|
if: steps.decide.outputs.enable == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.PKGS_BOT_TOKEN }}
|
||||||
|
PR: ${{ steps.pr.outputs.number }}
|
||||||
|
HEAD_SHA: ${{ steps.decide.outputs.head_sha }}
|
||||||
|
run: |
|
||||||
|
if [[ -z "$GH_TOKEN" ]]; then
|
||||||
|
echo "::error::Set PKGS_BOT_TOKEN; a GITHUB_TOKEN merge would not publish."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# Idempotent: enabling twice errors. Bot lanes enable their own.
|
||||||
|
if [[ "$(gh pr view "$PR" -R "$GITHUB_REPOSITORY" --json autoMergeRequest --jq '.autoMergeRequest != null')" == true ]]; then
|
||||||
|
echo "auto-merge already enabled on #$PR"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
# --match-head-commit: never arm a merge for a commit newer than
|
||||||
|
# the one just judged.
|
||||||
|
gh pr merge --auto --squash --match-head-commit "$HEAD_SHA" "$PR" -R "$GITHUB_REPOSITORY"
|
||||||
|
|
||||||
|
# Removing build-approved withdraws the approval, so withdraw the
|
||||||
|
# auto-merge it armed too. Only on that event: auto-merge a maintainer
|
||||||
|
# enabled by hand on any other PR is theirs to keep.
|
||||||
|
- name: Withdraw auto-merge
|
||||||
|
if: >-
|
||||||
|
steps.decide.outputs.enable == 'false' &&
|
||||||
|
github.event.action == 'unlabeled' && github.event.label.name == 'build-approved'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.PKGS_BOT_TOKEN }}
|
||||||
|
PR: ${{ steps.pr.outputs.number }}
|
||||||
|
run: |
|
||||||
|
if [[ "$(gh pr view "$PR" -R "$GITHUB_REPOSITORY" --json autoMergeRequest --jq '.autoMergeRequest != null')" == true ]]; then
|
||||||
|
gh pr merge --disable-auto "$PR" -R "$GITHUB_REPOSITORY"
|
||||||
|
fi
|
||||||
@@ -24,11 +24,10 @@ on:
|
|||||||
description: "Space-separated package directories to publish from master"
|
description: "Space-separated package directories to publish from master"
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
# Merges serialize. Two publishes into one channel at once would race on
|
# Only the publish job serializes (see its concurrency group): two publishes
|
||||||
# the database; queued is fine, cancelled is not.
|
# into one channel at once would race on the database. Builds run outside the
|
||||||
concurrency:
|
# lock, so a merge waits behind another merge's signing and upload, seconds,
|
||||||
group: publish
|
# never behind its kernel build.
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
changes:
|
changes:
|
||||||
@@ -58,11 +57,10 @@ jobs:
|
|||||||
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
|
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
|
||||||
echo "count=$(jq '.include | length' <<<"$matrix")" >> "$GITHUB_OUTPUT"
|
echo "count=$(jq '.include | length' <<<"$matrix")" >> "$GITHUB_OUTPUT"
|
||||||
jq -r '.include[] | "\(.package) \(.arch) -> \(.channels)"' <<<"$matrix"
|
jq -r '.include[] | "\(.package) \(.arch) -> \(.channels)"' <<<"$matrix"
|
||||||
# Reuse or rebuild, decided per entry and said out loud. An aarch64
|
# Reuse or rebuild, decided per entry and said out loud. A tree with
|
||||||
# tree with no build artifact (PR artifacts last 7 days; a dispatch
|
# no build artifact (PR artifacts last 7 days; a dispatch may name
|
||||||
# may name any package) goes to the rebuild job, which builds it
|
# any package) goes to the rebuild job: aarch64 natively on GitHub's
|
||||||
# natively on GitHub's arm64 runner. x86_64 builds inside the
|
# arm64 runner, x86_64 on a builder droplet, one runner per entry.
|
||||||
# publish job on the droplet, as before.
|
|
||||||
rebuild=()
|
rebuild=()
|
||||||
echo "| package | arch | tree | decision |" >> "$GITHUB_STEP_SUMMARY"
|
echo "| package | arch | tree | decision |" >> "$GITHUB_STEP_SUMMARY"
|
||||||
echo "| --- | --- | --- | --- |" >> "$GITHUB_STEP_SUMMARY"
|
echo "| --- | --- | --- | --- |" >> "$GITHUB_STEP_SUMMARY"
|
||||||
@@ -73,13 +71,23 @@ jobs:
|
|||||||
found=$(curl -fsS -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
|
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" \
|
"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 | select(. != null) | "run \(.workflow_run.id), expires \(.expires_at)"')
|
| jq -r '[.artifacts[] | select(.expired|not)] | sort_by(.created_at) | last | select(. != null) | "run \(.workflow_run.id), expires \(.expires_at)"')
|
||||||
|
# The plan the publish job makes, made here before a runner is
|
||||||
|
# asked for: a tree the channel already holds at master's version
|
||||||
|
# (a re-run, or a dispatch naming a package that is fine) needs
|
||||||
|
# no build, and an x86 rebuild would wait minutes for a droplet
|
||||||
|
# to find that out in seconds.
|
||||||
|
plan=""
|
||||||
|
[[ -n "$found" ]] || plan=$(bin/build --dry-run --mirror edge --arch "$arch" --package "$package" 2>&1 | grep -E '^==> Plan complete' || true)
|
||||||
if [[ -n "$found" ]]; then
|
if [[ -n "$found" ]]; then
|
||||||
decision="reuse the build artifact ($found)"
|
decision="reuse the build artifact ($found)"
|
||||||
|
elif [[ -n "$plan" && -z "$(sed -E 's/.*would build: *//' <<<"$plan" | tr -d '[:space:]')" ]]; then
|
||||||
|
decision="already published at master's version, nothing to build"
|
||||||
elif [[ $arch == aarch64 ]]; then
|
elif [[ $arch == aarch64 ]]; then
|
||||||
decision="no build artifact: rebuild natively on ubuntu-24.04-arm"
|
decision="no build artifact: rebuild natively on ubuntu-24.04-arm"
|
||||||
rebuild+=("$entry")
|
rebuild+=("$(jq -c '. + {runner: "[\"ubuntu-24.04-arm\"]"}' <<<"$entry")")
|
||||||
else
|
else
|
||||||
decision="no build artifact: build in the publish job on the self-hosted builder"
|
decision="no build artifact: rebuild on a builder droplet"
|
||||||
|
rebuild+=("$(jq -c '. + {runner: "[\"self-hosted\",\"omarchy-builder\"]"}' <<<"$entry")")
|
||||||
fi
|
fi
|
||||||
echo "==> $label: $decision"
|
echo "==> $label: $decision"
|
||||||
echo "| $package | $arch | ${hash:0:12} | $decision |" >> "$GITHUB_STEP_SUMMARY"
|
echo "| $package | $arch | ${hash:0:12} | $decision |" >> "$GITHUB_STEP_SUMMARY"
|
||||||
@@ -87,16 +95,19 @@ jobs:
|
|||||||
echo "rebuild=$(printf '%s\n' "${rebuild[@]}" | jq -sc '{include: .}')" >> "$GITHUB_OUTPUT"
|
echo "rebuild=$(printf '%s\n' "${rebuild[@]}" | jq -sc '{include: .}')" >> "$GITHUB_OUTPUT"
|
||||||
echo "rebuild_count=${#rebuild[@]}" >> "$GITHUB_OUTPUT"
|
echo "rebuild_count=${#rebuild[@]}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# The aarch64 half of "build it now when there is none". It builds exactly
|
# "Build it now when there is none". Each entry builds exactly as
|
||||||
# as build-pr.yml's aarch64 path does (same runner, same builder image,
|
# build-pr.yml builds it (same runner kind, same builder image, same
|
||||||
# same bin/build call) and uploads under the same label, so the publish
|
# bin/build call) and uploads under the same label, so the publish job
|
||||||
# job collects this run's artifact the way it collects a PR's. No secret
|
# collects this run's artifact the way it collects a PR's. No secret
|
||||||
# reaches this runner; signing and upload stay on the self-hosted builder.
|
# reaches these runners, and they hold no lock: entries build in parallel,
|
||||||
|
# and other merges publish while they do.
|
||||||
rebuild:
|
rebuild:
|
||||||
needs: changes
|
needs: changes
|
||||||
if: needs.changes.outputs.rebuild_count != '0'
|
if: needs.changes.outputs.rebuild_count != '0'
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ${{ fromJSON(matrix.runner) }}
|
||||||
timeout-minutes: 180
|
# The droplets are x86, so aarch64 never builds there. omarchy-mac-boot
|
||||||
|
# under QEMU took 2h47m; native arm64 and x86 kernels fit easily.
|
||||||
|
timeout-minutes: 240
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
strategy:
|
strategy:
|
||||||
@@ -109,7 +120,7 @@ jobs:
|
|||||||
# The same check the publish job makes before building: a re-run for a
|
# The same check the publish job makes before building: a re-run for a
|
||||||
# package the channel already holds at master's version builds
|
# package the channel already holds at master's version builds
|
||||||
# nothing, and uploads nothing that could shadow the published file.
|
# nothing, and uploads nothing that could shadow the published file.
|
||||||
- name: Build ${{ matrix.package }} (${{ matrix.arch }}, native)
|
- name: Build ${{ matrix.package }} (${{ matrix.arch }})
|
||||||
id: build
|
id: build
|
||||||
env:
|
env:
|
||||||
CONTAINER_ENGINE: docker
|
CONTAINER_ENGINE: docker
|
||||||
@@ -140,23 +151,26 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
# One job for the whole merge. It collects every PR artifact for the
|
# One job for the whole merge. It collects every artifact for the merged
|
||||||
# merged tree (building only what has none; aarch64 comes from the
|
# tree (PR builds, or the rebuild job above), then walks each channel and
|
||||||
# rebuild job above), then walks each channel and
|
|
||||||
# architecture slot exactly once: pull that database, add every package
|
# architecture slot exactly once: pull that database, add every package
|
||||||
# that belongs in it, upload. Six slots, six round trips, however many
|
# that belongs in it, upload. Six slots, six round trips, however many
|
||||||
# packages the merge carried. One process is the only writer, so there
|
# packages the merge carried. One process is the only writer, so there
|
||||||
# is no race between packages; the run-level concurrency group above
|
# is no race between packages; the concurrency group keeps one merge's
|
||||||
# keeps one merge from overlapping the next.
|
# publish from overlapping the next. It builds nothing, so it runs on a
|
||||||
|
# hosted runner in about a minute instead of waiting for a droplet.
|
||||||
# It waits for the rebuild job and runs whatever that job's result: a
|
# It waits for the rebuild job and runs whatever that job's result: a
|
||||||
# failed rebuild leaves its package without an artifact, and the collect
|
# failed rebuild leaves its package without an artifact, and the collect
|
||||||
# step below records that and stops before any publish.
|
# step below records that and stops before any publish.
|
||||||
publish:
|
publish:
|
||||||
needs: [changes, rebuild]
|
needs: [changes, rebuild]
|
||||||
if: ${{ !cancelled() && needs.changes.result == 'success' && needs.changes.outputs.count != '0' }}
|
if: ${{ !cancelled() && needs.changes.result == 'success' && needs.changes.outputs.count != '0' }}
|
||||||
runs-on: [self-hosted, omarchy-builder]
|
runs-on: ubuntu-latest
|
||||||
environment: publish
|
environment: publish
|
||||||
timeout-minutes: 240
|
timeout-minutes: 30
|
||||||
|
concurrency:
|
||||||
|
group: publish
|
||||||
|
cancel-in-progress: false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -172,8 +186,8 @@ jobs:
|
|||||||
EOF_MATRIX
|
EOF_MATRIX
|
||||||
cat plan.txt
|
cat plan.txt
|
||||||
|
|
||||||
# Fetch each package's PR artifact into build-output/edge/<arch>/, or
|
# Fetch each package's artifact into build-output/edge/<arch>/: the PR's,
|
||||||
# build it when no artifact exists for exactly this tree. An artifact
|
# or the rebuild job's when the PR's had expired. An artifact
|
||||||
# carries its package files inside packages.tar (see build-pr.yml and
|
# carries its package files inside packages.tar (see build-pr.yml and
|
||||||
# helpers/artifact-helpers.sh: the upload action rejects the colon in
|
# helpers/artifact-helpers.sh: the upload action rejects the colon in
|
||||||
# an epoch filename).
|
# an epoch filename).
|
||||||
@@ -199,8 +213,8 @@ jobs:
|
|||||||
mkdir -p "build-output/edge/$arch"
|
mkdir -p "build-output/edge/$arch"
|
||||||
if [[ -n "$found" ]]; then
|
if [[ -n "$found" ]]; then
|
||||||
if [[ $from_run == "${{ github.run_id }}" ]]; then
|
if [[ $from_run == "${{ github.run_id }}" ]]; then
|
||||||
kind=native-rebuild
|
kind=rebuild
|
||||||
echo "==> $label: artifact from this run's native $arch rebuild"
|
echo "==> $label: artifact from this run's $arch rebuild"
|
||||||
else
|
else
|
||||||
kind=pr-artifact
|
kind=pr-artifact
|
||||||
echo "==> $label: reusing the build artifact from run $from_run"
|
echo "==> $label: reusing the build artifact from run $from_run"
|
||||||
@@ -225,20 +239,11 @@ jobs:
|
|||||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"already-published"}' >> sources.jsonl
|
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"already-published"}' >> sources.jsonl
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# aarch64 never builds here: this droplet is x86 and would
|
# Nothing builds here. No artifact means the rebuild failed (see
|
||||||
# emulate it. No artifact means the native rebuild failed (see
|
# the rebuild job), or an artifact expired between planning and
|
||||||
# the rebuild job), or an artifact expired between planning
|
# now (re-run all jobs).
|
||||||
# and now (re-run all jobs).
|
echo "::error::$label: no artifact from the rebuild job"
|
||||||
if [[ $arch == aarch64 ]]; then
|
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"build-failed"}' >> sources.jsonl; failed=1; break
|
||||||
echo "::error::$label: no artifact from the native rebuild; not building aarch64 under emulation"
|
|
||||||
jq -nc --arg p "$package" --arg a "$arch" '{package:$p, arch:$a, source:"native-build-failed"}' >> sources.jsonl; failed=1; break
|
|
||||||
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
|
fi
|
||||||
done < plan.txt
|
done < plan.txt
|
||||||
ls -1 build-output/edge/*/*.pkg.tar.zst 2>/dev/null || true
|
ls -1 build-output/edge/*/*.pkg.tar.zst 2>/dev/null || true
|
||||||
@@ -280,8 +285,26 @@ jobs:
|
|||||||
cat publish-record.json
|
cat publish-record.json
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
docker image inspect omarchy-pkg-builder:latest-x86_64-edge >/dev/null 2>&1 \
|
# A fresh runner has no images, and building this one here cost
|
||||||
|| docker buildx build --load -t omarchy-pkg-builder:latest-x86_64-edge --build-arg MIRROR=edge build
|
# every publish about 100 s (and 20 s more to start a container
|
||||||
|
# from it) for the 14 s of signing and upload it is needed for.
|
||||||
|
# builder-images.yml already publishes the tested image for exactly
|
||||||
|
# these build inputs under their key; pull that. Build only when no
|
||||||
|
# image carries the key: a merge that changed build/ publishes
|
||||||
|
# before the refresh it triggered has finished.
|
||||||
|
builder=omarchy-pkg-builder:latest-x86_64-edge
|
||||||
|
if ! docker image inspect "$builder" >/dev/null 2>&1; then
|
||||||
|
key=$(bin/builder-image key --arch x86_64 --mirror edge)
|
||||||
|
published="ghcr.io/omacom/omarchy-pkg-builder:$key"
|
||||||
|
if docker pull --quiet "$published" &&
|
||||||
|
[[ $(docker image inspect "$published" --format '{{index .Config.Labels "org.omarchy.builder.key"}}') == "$key" ]]; then
|
||||||
|
docker tag "$published" "$builder"
|
||||||
|
echo "==> Builder image: pulled $published"
|
||||||
|
else
|
||||||
|
echo "==> Builder image: none published for $key, building it"
|
||||||
|
docker buildx build --load -t "$builder" --build-arg MIRROR=edge build
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Group the merge's files by the (channel, architecture) slot each
|
# Group the merge's files by the (channel, architecture) slot each
|
||||||
# belongs to. A package's files live under build-output/edge/<built
|
# belongs to. A package's files live under build-output/edge/<built
|
||||||
@@ -374,7 +397,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
jq -r --arg outcome "${{ needs.publish.result }}" '
|
jq -r --arg outcome "${{ needs.publish.result }}" '
|
||||||
def pkgs: [.packages[] | select(test("-debug-")|not)] | join(", ");
|
def pkgs: [.packages[] | select(test("-debug-")|not)] | join(", ");
|
||||||
def src: if .source=="pr-artifact" then "PR artifact" elif .source=="native-rebuild" then "rebuilt natively on arm64" elif .source=="built" then "built here" elif .source=="already-published" then "already published, skipped" else "**" + .source + "**" end;
|
def src: if .source=="pr-artifact" then "PR artifact" elif .source=="rebuild" or .source=="native-rebuild" then "rebuilt at merge" 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) +
|
"### Publish " + (if $outcome=="success" then "succeeded" else "FAILED" end) +
|
||||||
" → **" + .target + "**" + (if .target!="live" then " (proof prefix, not live)" else "" end),
|
" → **" + .target + "**" + (if .target!="live" then " (proof prefix, not live)" else "" end),
|
||||||
"",
|
"",
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
name: Sync Rebuild Triggers
|
name: Sync Rebuild Triggers
|
||||||
|
|
||||||
|
# Rebuilds ride the unattended lane, like track-branches.yml: the pkgrel bump
|
||||||
|
# PR builds on the droplets, auto-merge lands it once `result`, `self-tests`
|
||||||
|
# and `build-isolation` are green, and the merge publishes. A rebuild that
|
||||||
|
# fails stays an unmerged red PR for a maintainer.
|
||||||
|
#
|
||||||
|
# The PR and auto-merge use the PAT in PKGS_BOT_TOKEN, because a merge made
|
||||||
|
# with the built-in GITHUB_TOKEN does not start publish.yml, and its pushes
|
||||||
|
# are held for approval instead of building.
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
# Every 6 hours, off the hour to dodge the scheduling backlog at :00
|
# Every 6 hours, off the hour to dodge the scheduling backlog at :00
|
||||||
@@ -17,14 +26,17 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
outputs:
|
|
||||||
branch: ${{ steps.branch.outputs.branch }}
|
|
||||||
pushed_at: ${{ steps.pushed.outputs.at }}
|
|
||||||
number: ${{ steps.cpr.outputs.pull-request-number }}
|
|
||||||
operation: ${{ steps.cpr.outputs.pull-request-operation }}
|
|
||||||
head_sha: ${{ steps.cpr.outputs.pull-request-head-sha }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Require the bot token
|
||||||
|
env:
|
||||||
|
PKGS_BOT_TOKEN: ${{ secrets.PKGS_BOT_TOKEN }}
|
||||||
|
run: |
|
||||||
|
if [[ -z "$PKGS_BOT_TOKEN" ]]; then
|
||||||
|
echo "::error::Set PKGS_BOT_TOKEN to a PAT with Contents: write and Pull requests: write on this repository, owned by an account trusted to trigger builds."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -85,19 +97,12 @@ jobs:
|
|||||||
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Runs created by this push are newer than this; the approve job
|
|
||||||
# waits for them. A minute's slack absorbs runner clock skew.
|
|
||||||
- name: Record push time
|
|
||||||
if: steps.changes.outputs.has_changes == 'true'
|
|
||||||
id: pushed
|
|
||||||
run: echo "at=$(date -u -d '-1 minute' +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
if: steps.changes.outputs.has_changes == 'true'
|
if: steps.changes.outputs.has_changes == 'true'
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.PKGS_BOT_TOKEN }}
|
||||||
commit-message: 'chore: rebuild against updated dependencies'
|
commit-message: 'chore: rebuild against updated dependencies'
|
||||||
title: "chore: rebuild against updated dependencies${{ steps.branch.outputs.scope && format(' ({0})', steps.branch.outputs.scope) || '' }}"
|
title: "chore: rebuild against updated dependencies${{ steps.branch.outputs.scope && format(' ({0})', steps.branch.outputs.scope) || '' }}"
|
||||||
body: |
|
body: |
|
||||||
@@ -109,14 +114,27 @@ jobs:
|
|||||||
bump is what makes the rebuilt package an upgrade pacman will offer;
|
bump is what makes the rebuilt package an upgrade pacman will offer;
|
||||||
without it the build produces the version already published and no
|
without it the build produces the version already published and no
|
||||||
one receives it.
|
one receives it.
|
||||||
|
|
||||||
|
This PR auto-merges once the build checks pass. A failing rebuild
|
||||||
|
leaves it open for a maintainer.
|
||||||
branch: ${{ steps.branch.outputs.branch }}
|
branch: ${{ steps.branch.outputs.branch }}
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
# The bot is trusted; build-approved lets the approve job below
|
labels: automated
|
||||||
# release GitHub's hold on its pushes without a maintainer.
|
|
||||||
labels: |
|
# Auto-merge, not a direct merge: branch protection still has to see
|
||||||
automated
|
# the build checks green before the rebuild lands.
|
||||||
build-approved
|
- name: Enable auto-merge
|
||||||
reviewers: ryanrhughes
|
if: steps.cpr.outputs.pull-request-number != ''
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.PKGS_BOT_TOKEN }}
|
||||||
|
PR: ${{ steps.cpr.outputs.pull-request-number }}
|
||||||
|
run: |
|
||||||
|
# Idempotent across re-runs of an updated PR: enabling twice errors.
|
||||||
|
if [[ "$(gh pr view "$PR" -R "${{ github.repository }}" --json autoMergeRequest --jq '.autoMergeRequest != null')" == true ]]; then
|
||||||
|
echo "auto-merge already enabled on #$PR"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
gh pr merge --auto --merge "$PR" -R "${{ github.repository }}"
|
||||||
|
|
||||||
- name: Notify Basecamp on failure
|
- name: Notify Basecamp on failure
|
||||||
if: failure() && env.BASECAMP_CHATBOT_URL != ''
|
if: failure() && env.BASECAMP_CHATBOT_URL != ''
|
||||||
@@ -129,36 +147,3 @@ jobs:
|
|||||||
"🔴 <strong>Rebuild trigger sync failed</strong><br><a href=\"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\">View run</a>" \
|
"🔴 <strong>Rebuild trigger sync failed</strong><br><a href=\"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\">View run</a>" \
|
||||||
'{content: $content}')" \
|
'{content: $content}')" \
|
||||||
"$BASECAMP_CHATBOT_URL"
|
"$BASECAMP_CHATBOT_URL"
|
||||||
|
|
||||||
# GitHub holds pull_request runs from a GITHUB_TOKEN push for approval and
|
|
||||||
# creates no pull_request_target run for it, so approve-pr.yml never sees
|
|
||||||
# the sync's own pushes. The sync labels its PR build-approved, so release
|
|
||||||
# the held runs for the commit just pushed, whether it opened the PR or
|
|
||||||
# updated it. A separate job, so the sync container's token never holds
|
|
||||||
# actions: write.
|
|
||||||
approve:
|
|
||||||
needs: sync
|
|
||||||
if: ${{ !cancelled() && (needs.sync.outputs.operation == 'created' || needs.sync.outputs.operation == 'updated') }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 5
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: read
|
|
||||||
actions: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
- name: Release held build and test runs
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
env:
|
|
||||||
NUMBER: ${{ needs.sync.outputs.number }}
|
|
||||||
BRANCH: ${{ needs.sync.outputs.branch }}
|
|
||||||
HEAD_SHA: ${{ needs.sync.outputs.head_sha }}
|
|
||||||
SINCE: ${{ needs.sync.outputs.pushed_at }}
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const approve = require('./.github/scripts/approve-sync-push.cjs');
|
|
||||||
const { NUMBER, BRANCH, HEAD_SHA, SINCE } = process.env;
|
|
||||||
await approve({ github, context, core, number: Number(NUMBER),
|
|
||||||
branch: BRANCH, headSha: HEAD_SHA, since: SINCE });
|
|
||||||
@@ -67,6 +67,7 @@ jobs:
|
|||||||
./tests/artifact-helpers.sh
|
./tests/artifact-helpers.sh
|
||||||
./tests/limine-mkinitcpio-hook.sh
|
./tests/limine-mkinitcpio-hook.sh
|
||||||
./tests/voxtype-bin-install.sh
|
./tests/voxtype-bin-install.sh
|
||||||
|
./tests/superwhisper-bin-install.sh
|
||||||
pacman -S --noconfirm --quiet rclone >/dev/null
|
pacman -S --noconfirm --quiet rclone >/dev/null
|
||||||
./tests/publish-artifact.sh
|
./tests/publish-artifact.sh
|
||||||
'
|
'
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
name: Unpublish retired packages
|
||||||
|
|
||||||
|
# Takes packages out of the channel databases after their recipes are gone
|
||||||
|
# from master. Deleting a recipe stops it building; this stops pacman
|
||||||
|
# offering it. Files stay in the bucket (see bin/unpublish-packages).
|
||||||
|
#
|
||||||
|
# Only packages with no recipe on master: one that still has a recipe would
|
||||||
|
# come back on its next publish, and refusing it keeps a typo from pulling a
|
||||||
|
# live package out of every channel.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
description: "Space-separated pkgbases whose recipes were removed from master"
|
||||||
|
required: true
|
||||||
|
channels:
|
||||||
|
description: "Channels to remove them from"
|
||||||
|
required: true
|
||||||
|
default: "edge rc stable"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unpublish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: publish
|
||||||
|
timeout-minutes: 15
|
||||||
|
# The publish job's group: one writer per channel database at a time.
|
||||||
|
concurrency:
|
||||||
|
group: publish
|
||||||
|
cancel-in-progress: false
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Refuse packages that still have a recipe
|
||||||
|
env:
|
||||||
|
PACKAGES: ${{ github.event.inputs.packages }}
|
||||||
|
CHANNELS: ${{ github.event.inputs.channels }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for c in $CHANNELS; do
|
||||||
|
[[ $c == edge || $c == rc || $c == stable ]] || { echo "::error::Unknown channel: $c"; exit 1; }
|
||||||
|
done
|
||||||
|
for p in $PACKAGES; do
|
||||||
|
[[ $p =~ ^[a-z0-9@._+-]+$ ]] || { echo "::error::Not a package name: $p"; exit 1; }
|
||||||
|
if [[ -e pkgbuilds/$p ]]; then
|
||||||
|
echo "::error::pkgbuilds/$p still exists on master; remove the recipe first"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Unpublish
|
||||||
|
env:
|
||||||
|
PACKAGES: ${{ github.event.inputs.packages }}
|
||||||
|
CHANNELS: ${{ github.event.inputs.channels }}
|
||||||
|
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 }}
|
||||||
|
OMARCHY_PUBLISH_PREFIX: ${{ vars.OMARCHY_PUBLISH_PREFIX }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
# repo-remove and bsdtar are Arch tools: run in the tested builder
|
||||||
|
# image, as the publish job does.
|
||||||
|
builder=ghcr.io/omacom/omarchy-pkg-builder:$(bin/builder-image key --arch x86_64 --mirror edge)
|
||||||
|
docker pull --quiet "$builder"
|
||||||
|
for mirror in $CHANNELS; do
|
||||||
|
for arch in x86_64 aarch64; do
|
||||||
|
docker run --rm \
|
||||||
|
-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 "$builder" \
|
||||||
|
bin/unpublish-packages --remote R2:omarchy-pkgs --mirror "$mirror" --arch "$arch" $PACKAGES
|
||||||
|
done
|
||||||
|
done
|
||||||
@@ -565,12 +565,26 @@ bin/repo deploy # Build locally, then publish from the host
|
|||||||
bin/repo push # Upload local builds to the host and publish
|
bin/repo push # Upload local builds to the host and publish
|
||||||
bin/add-package <package> # Add an Omarchy-owned package with metadata
|
bin/add-package <package> # Add an Omarchy-owned package with metadata
|
||||||
bin/package-worktree <package> # Inspect historical AUR provenance in a scratch workspace
|
bin/package-worktree <package> # Inspect historical AUR provenance in a scratch workspace
|
||||||
bin/repo remove <package> # Remove package
|
bin/repo remove <package> # Remove package (host workflow; CI uses unpublish.yml)
|
||||||
bin/sync-upstream # Update packages that track a vendor release feed
|
bin/sync-upstream # Update packages that track a vendor release feed
|
||||||
bin/sync-rebuilds # Bump pkgrel for packages whose dependencies moved
|
bin/sync-rebuilds # Bump pkgrel for packages whose dependencies moved
|
||||||
bin/clean-docker # Clear Docker images/cache (forces fresh rebuild)
|
bin/clean-docker # Clear Docker images/cache (forces fresh rebuild)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Retiring a package
|
||||||
|
|
||||||
|
Delete its recipe directory in a PR. Once that merges, take it out of the
|
||||||
|
channel databases with the **Unpublish retired packages** workflow:
|
||||||
|
|
||||||
|
```
|
||||||
|
gh workflow run unpublish.yml -f packages="<pkgbase> ..." -f channels="edge rc stable"
|
||||||
|
```
|
||||||
|
|
||||||
|
It removes every entry built from those pkgbases (split outputs and `-debug`
|
||||||
|
included) from both architectures' databases, and refuses any package that
|
||||||
|
still has a recipe on master. Package files stay in the bucket: published
|
||||||
|
filenames are immutable, and nothing references them once the entries are gone.
|
||||||
|
|
||||||
### Package Metadata Tools
|
### Package Metadata Tools
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -893,15 +907,15 @@ The repository includes GitHub workflows and systemd services for automated rele
|
|||||||
#### GitHub Workflows
|
#### GitHub Workflows
|
||||||
|
|
||||||
1. **sync-upstream.yml** (Every 6 hours): Watches direct upstream feeds and updates owned recipes on the reviewed lane. Successful package updates reach a PR even if another feed fails; failed recipes stay untouched and the workflow remains red.
|
1. **sync-upstream.yml** (Every 6 hours): Watches direct upstream feeds and updates owned recipes on the reviewed lane. 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.
|
2. **sync-rebuilds.yml** (Every 6 hours): Bumps pkgrel for packages whose `rebuild_on` dependencies have moved in the official repositories, opens a PR, and enables auto-merge. The PR lands once its build checks pass; a rebuild that fails stays an open red PR for a maintainer.
|
||||||
3. **track-branches.yml** (Every 2 hours): The unattended lane. Pins every `"auto_merge": true` package to the tip of its watched branch once its commit timestamp clears `min_release_age`, opens one PR for all of them, and enables auto-merge. Packages pinned from the same branch move together or not at all, including targeted syncs. The PR builds like any other; a tip that fails to build stays an open red PR until the next tick supersedes it.
|
3. **track-branches.yml** (Every 2 hours): The unattended lane. Pins every `"auto_merge": true` package to the tip of its watched branch once its commit timestamp clears `min_release_age`, opens one PR for all of them, and enables auto-merge. Packages pinned from the same branch move together or not at all, including targeted syncs. The PR builds like any other; a tip that fails to build stays an open red PR until the next tick supersedes it.
|
||||||
|
|
||||||
The tracking PR and auto-merge use the PAT stored in `PKGS_BOT_TOKEN`, with
|
The tracking and rebuild PRs and their auto-merge use the PAT stored in `PKGS_BOT_TOKEN`, with
|
||||||
Contents and Pull requests write access to this repository and an owner trusted
|
Contents and Pull requests write access to this repository and an owner trusted
|
||||||
to trigger builds. The existing controller PAT can be reused. No GitHub App is
|
to trigger builds. The existing controller PAT can be reused. No GitHub App is
|
||||||
required. The built-in Actions `GITHUB_TOKEN` cannot drive the unattended
|
required. The built-in Actions `GITHUB_TOKEN` cannot drive the unattended
|
||||||
build-and-publish chain, so the tracker requires this secret before it runs.
|
build-and-publish chain, so both workflows require this secret before they run.
|
||||||
The reviewed sync workflows continue to use `GITHUB_TOKEN` and require
|
The reviewed upstream sync continues to use `GITHUB_TOKEN` and requires
|
||||||
maintainer approval as before. See [setup instructions](docs/upstream-sources.md#enable-unattended-branch-updates).
|
maintainer approval as before. See [setup instructions](docs/upstream-sources.md#enable-unattended-branch-updates).
|
||||||
|
|
||||||
Scheduled runs regenerate one shared PR (`auto/sync-upstream`, `auto/sync-rebuilds`)
|
Scheduled runs regenerate one shared PR (`auto/sync-upstream`, `auto/sync-rebuilds`)
|
||||||
@@ -912,14 +926,27 @@ pending updates. The next scheduled run still picks the same update up in the
|
|||||||
shared PR if it has not merged by then; identical package trees reuse the same
|
shared PR if it has not merged by then; identical package trees reuse the same
|
||||||
build artifacts.
|
build artifacts.
|
||||||
|
|
||||||
Sync PRs are pushed with `GITHUB_TOKEN`, so GitHub holds their build and test
|
Upstream sync PRs are pushed with `GITHUB_TOKEN`, so GitHub holds their build and test
|
||||||
runs for approval on every push and starts no `pull_request_target` workflow
|
runs for approval on every push and starts no `pull_request_target` workflow
|
||||||
for them. The sync workflows label their own PRs **`build-approved`**, and
|
for them. The upstream sync labels its own PRs **`build-approved`**, and
|
||||||
their `approve` job releases the held runs for each commit they push, including
|
its `approve` job releases the held runs for each commit they push, including
|
||||||
the push that opens the PR. A push to an `auto/sync-*` branch does not cancel
|
the push that opens the PR. A push to an `auto/sync-*` branch does not cancel
|
||||||
the PR's in-flight build: the new build waits for it and then reuses its
|
the PR's in-flight build: the new build waits for it and then reuses its
|
||||||
artifacts, so a long aarch64 build is not restarted by every sync.
|
artifacts, so a long aarch64 build is not restarted by every sync.
|
||||||
|
|
||||||
|
Package PRs that are trusted to build also merge themselves.
|
||||||
|
`auto-merge-pr.yml` enables auto-merge (with `PKGS_BOT_TOKEN`, so the merge
|
||||||
|
publishes) on any open, non-draft PR whose author is a collaborator, vouched,
|
||||||
|
or a bot, or that carries **`build-approved`**, and that changes only
|
||||||
|
packages: anything under `pkgbuilds/`, plus the test a package PR brings with
|
||||||
|
it (a new file under `tests/`, and `test.yml` lines that only run new
|
||||||
|
`./tests/*.sh`). The PR lands once `result`, `self-tests` and
|
||||||
|
`build-isolation` pass; a red build stays open. PRs that also touch
|
||||||
|
workflows, scripts, build tooling or existing tests still need a maintainer, as does
|
||||||
|
the upstream sync (`auto/sync-upstream`), which labels itself. Removing
|
||||||
|
`build-approved` withdraws the auto-merge it armed. For a PR opened before
|
||||||
|
the workflow existed, run it by hand: `gh workflow run auto-merge-pr.yml -f pr=<number>`.
|
||||||
|
|
||||||
To approve builds for an unvouched contributor's PR, apply **`build-approved`**.
|
To approve builds for an unvouched contributor's PR, apply **`build-approved`**.
|
||||||
Until approval, the PR shows **Awaiting build approval** and its required
|
Until approval, the PR shows **Awaiting build approval** and its required
|
||||||
`result` check stays pending, keeping the PR blocked from merging without
|
`result` check stays pending, keeping the PR blocked from merging without
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
echo " $0 --arch aarch64"
|
echo " $0 --arch aarch64"
|
||||||
echo " $0 --mirror stable"
|
echo " $0 --mirror stable"
|
||||||
echo " $0 --package yay"
|
echo " $0 --package yay"
|
||||||
echo " $0 --package yay elephant cursor-bin"
|
echo " $0 --package yay walker cursor-bin"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Environment (for CI and resumed builds; defaults keep today's behaviour):"
|
echo "Environment (for CI and resumed builds; defaults keep today's behaviour):"
|
||||||
echo " OMARCHY_KEEP_BUILD_WORKSPACE=1 keep build-output and reuse packages already there"
|
echo " OMARCHY_KEEP_BUILD_WORKSPACE=1 keep build-output and reuse packages already there"
|
||||||
|
|||||||
Executable
+80
@@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Retire packages from one channel of the remote repository.
|
||||||
|
#
|
||||||
|
# unpublish-packages --mirror <edge|rc|stable> --arch <arch> <pkgbase...>
|
||||||
|
#
|
||||||
|
# The counterpart of publish-artifact, with the same steps:
|
||||||
|
# 1. pull the channel's current database from the remote
|
||||||
|
# 2. find every entry built from the named pkgbases (so a package's split
|
||||||
|
# outputs and -debug go with it)
|
||||||
|
# 3. repo-remove them
|
||||||
|
# 4. upload the database
|
||||||
|
#
|
||||||
|
# Package files stay in the bucket. Published filenames are immutable and the
|
||||||
|
# R2 cache cannot recover from a rewrite; an unreferenced file costs nothing
|
||||||
|
# and pacman never sees it. Naming a package the channel does not hold is not
|
||||||
|
# an error, so a re-run is harmless.
|
||||||
|
#
|
||||||
|
# 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:-}
|
||||||
|
BASES=()
|
||||||
|
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,19p' "$0"; exit 0 ;;
|
||||||
|
-*) print_error "Unknown option: $1"; exit 1 ;;
|
||||||
|
*) BASES+=("$1"); shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
(( ${#BASES[@]} )) || { print_error "No packages given"; exit 1; }
|
||||||
|
|
||||||
|
DEST="$REMOTE/${PREFIX:+$PREFIX/}$MIRROR/$ARCH"
|
||||||
|
WORK=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$WORK"' EXIT
|
||||||
|
print_header "Unpublish from $DEST"
|
||||||
|
|
||||||
|
# --- 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
|
||||||
|
print_info "No database at $DEST; nothing to remove"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
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
|
||||||
|
before=$(tar -tf "$WORK/repo/omarchy.db.tar.zst" | grep -c '/$')
|
||||||
|
print_info "Pulled current database ($before entries)"
|
||||||
|
|
||||||
|
# --- 2. entries built from the named pkgbases -----------------------------
|
||||||
|
names=$(bsdtar -xOf "$WORK/repo/omarchy.db.tar.zst" --include '*/desc' |
|
||||||
|
awk -v bases=" ${BASES[*]} " '
|
||||||
|
/^%NAME%$/ { getline name }
|
||||||
|
/^%BASE%$/ { getline base; if (index(bases, " " base " ")) print name }')
|
||||||
|
if [[ -z "$names" ]]; then
|
||||||
|
print_info "None of ${BASES[*]} is in $MIRROR/$ARCH; nothing to remove"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
mapfile -t NAMES <<<"$names"
|
||||||
|
for n in "${NAMES[@]}"; do print_step "removing $n"; done
|
||||||
|
|
||||||
|
# --- 3. repo-remove ---------------------------------------------------------
|
||||||
|
( cd "$WORK/repo" && repo-remove --quiet omarchy.db.tar.zst "${NAMES[@]}" )
|
||||||
|
ln -sf omarchy.db.tar.zst "$WORK/repo/omarchy.db"
|
||||||
|
ln -sf omarchy.files.tar.zst "$WORK/repo/omarchy.files"
|
||||||
|
after=$(tar -tf "$WORK/repo/omarchy.db.tar.zst" | grep -c '/$')
|
||||||
|
(( before - after == ${#NAMES[@]} )) || {
|
||||||
|
print_error "Expected to remove ${#NAMES[@]} entries, removed $((before - after))"; exit 1; }
|
||||||
|
print_info "Database now has $after entries"
|
||||||
|
|
||||||
|
# --- 4. upload the database -------------------------------------------------
|
||||||
|
rclone copy "$WORK/repo" "$DEST" --s3-no-head --checksum --copy-links --filter '+ omarchy.db*' --filter '+ omarchy.files*' --filter '- *'
|
||||||
|
print_success "Removed ${#NAMES[@]} package(s) from $DEST"
|
||||||
+17
-4
@@ -12,9 +12,12 @@ signing on merge exactly as before.
|
|||||||
- `runner-cloud-init.yaml` — Ubuntu 24.04 user-data: docker + buildx, the
|
- `runner-cloud-init.yaml` — Ubuntu 24.04 user-data: docker + buildx, the
|
||||||
GitHub runner registered `--ephemeral`, runs one job, powers off.
|
GitHub runner registered `--ephemeral`, runs one job, powers off.
|
||||||
- `controller.sh` — systemd timer every minute on a small always-on droplet.
|
- `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
|
Polls for queued jobs with our label, creates one g5-32vcpu-64gb-50gb droplet per job up
|
||||||
to `MAX_DROPLETS`, deletes droplets that are powered off or older than
|
to `MAX_DROPLETS`, deletes droplets that are powered off or older than
|
||||||
`MAX_AGE_MINUTES`. No inbound endpoint. Plain curl against both APIs, no
|
`MAX_AGE_MINUTES`, or still provisioning after `MAX_BOOT_MINUTES`. Builders go in any region DigitalOcean lists the size in
|
||||||
|
stock in (`REGIONS` only sets which to try first); a refused create, logged
|
||||||
|
with DigitalOcean's message, falls back to the next region, then the next
|
||||||
|
of `SIZES`. No inbound endpoint. Plain curl against both APIs, no
|
||||||
doctl and no gh: a token in the environment cannot pick the wrong account
|
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.
|
the way a saved doctl context can. Needs curl and jq.
|
||||||
`tests/controller.sh` exercises every decision against canned responses.
|
`tests/controller.sh` exercises every decision against canned responses.
|
||||||
@@ -31,6 +34,13 @@ 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.
|
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.
|
Watch it with `journalctl -u omarchy-controller -f` on the box.
|
||||||
|
|
||||||
|
Each tick pulls the box's checkout first, so a merged `controller.sh` is live
|
||||||
|
within a minute. The unit and timer are copies made at creation; after
|
||||||
|
changing them, on the box:
|
||||||
|
|
||||||
|
cp /opt/omarchy-pkgs/ci/controller-box/omarchy-controller.{service,timer} /etc/systemd/system/
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
## What the spike proved (2026-09-17, fork ryanrhughes/omarchy-pkgs)
|
## What the spike proved (2026-09-17, fork ryanrhughes/omarchy-pkgs)
|
||||||
|
|
||||||
- `bin/build` works from a bare clone: with no local published tree it
|
- `bin/build` works from a bare clone: with no local published tree it
|
||||||
@@ -70,8 +80,11 @@ Watch it with `journalctl -u omarchy-controller -f` on the box.
|
|||||||
packages then signatures then the db.
|
packages then signatures then the db.
|
||||||
- aarch64 under QEMU with credential-preserving binfmt. PR builds now run
|
- aarch64 under QEMU with credential-preserving binfmt. PR builds now run
|
||||||
aarch64 natively on `ubuntu-24.04-arm` (QEMU was up to ~15x slower). When a
|
aarch64 natively on `ubuntu-24.04-arm` (QEMU was up to ~15x slower). When a
|
||||||
merged aarch64 tree has no artifact, publish.yml rebuilds it there too, in its
|
merged tree has no artifact, publish.yml rebuilds it in its own job, aarch64
|
||||||
own job, and signs and uploads it on the droplet like a PR artifact.
|
there and x86_64 on a droplet, outside the publish lock.
|
||||||
|
- Publish itself builds nothing: it signs and uploads on `ubuntu-latest` in the
|
||||||
|
tested builder image pulled from GHCR, and only that job holds the `publish`
|
||||||
|
concurrency group, so a merge waits for seconds of signing, not for builds.
|
||||||
- Vouch gate: collaborators, `.github/VOUCHED.td`, or the `build-approved`
|
- Vouch gate: collaborators, `.github/VOUCHED.td`, or the `build-approved`
|
||||||
label; denounced authors cannot be overridden by the label.
|
label; denounced authors cannot be overridden by the label.
|
||||||
- Tests run on PRs only; `result`, `self-tests`, `build-isolation` are the
|
- Tests run on PRs only; `result`, `self-tests`, `build-isolation` are the
|
||||||
|
|||||||
@@ -5,10 +5,14 @@ GITHUB_TOKEN=github_pat_...
|
|||||||
REPO=omacom/omarchy-pkgs
|
REPO=omacom/omarchy-pkgs
|
||||||
LABEL=omarchy-builder
|
LABEL=omarchy-builder
|
||||||
TAG=omarchy-builder
|
TAG=omarchy-builder
|
||||||
REGION=ric1
|
# Builder sizes, tried in order in any region that has them in stock.
|
||||||
SIZE=g5-32vcpu-64gb-50gb
|
SIZES="g5-32vcpu-64gb-50gb g5-32vcpu-128gb-50gb"
|
||||||
|
# Optional: regions to try first, e.g. "ric1". Empty means any.
|
||||||
|
REGIONS=
|
||||||
MAX_DROPLETS=6
|
MAX_DROPLETS=6
|
||||||
MAX_AGE_MINUTES=200
|
MAX_AGE_MINUTES=200
|
||||||
|
# Delete a droplet DigitalOcean still reports as provisioning after this long.
|
||||||
|
MAX_BOOT_MINUTES=10
|
||||||
LOCK=/run/omarchy-controller/lock
|
LOCK=/run/omarchy-controller/lock
|
||||||
# Operator public keys for root on every builder droplet (JSON array).
|
# Operator public keys for root on every builder droplet (JSON array).
|
||||||
# create.sh fills this from the operators' GitHub keys.
|
# create.sh fills this from the operators' GitHub keys.
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ Wants=network-online.target
|
|||||||
Type=oneshot
|
Type=oneshot
|
||||||
User=controller
|
User=controller
|
||||||
EnvironmentFile=/etc/omarchy-controller.env
|
EnvironmentFile=/etc/omarchy-controller.env
|
||||||
|
# Run the branch's current controller, not the one cloned when the box was
|
||||||
|
# built. As root (the checkout's owner); a failed pull keeps the last one.
|
||||||
|
ExecStartPre=-+/usr/bin/git -C /opt/omarchy-pkgs pull --ff-only --quiet
|
||||||
ExecStart=/opt/omarchy-pkgs/ci/controller.sh
|
ExecStart=/opt/omarchy-pkgs/ci/controller.sh
|
||||||
# The reaper's safety net is time, not state; a hung tick must not hold the lock.
|
# The reaper's safety net is time, not state; a hung tick must not hold the lock.
|
||||||
TimeoutStartSec=240
|
TimeoutStartSec=240
|
||||||
+88
-18
@@ -4,7 +4,8 @@
|
|||||||
# Run from a systemd timer every minute on a small always-on droplet. No
|
# 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
|
# inbound endpoint: it polls GitHub for queued jobs wanting our label, creates
|
||||||
# one ephemeral droplet per job (up to MAX_DROPLETS), and deletes droplets
|
# 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
|
# that have powered off, exceeded MAX_AGE_MINUTES, or are still provisioning
|
||||||
|
# after MAX_BOOT_MINUTES. The reaper does not
|
||||||
# trust its own bookkeeping: it lists by tag and acts on what DigitalOcean
|
# trust its own bookkeeping: it lists by tag and acts on what DigitalOcean
|
||||||
# reports.
|
# reports.
|
||||||
#
|
#
|
||||||
@@ -21,11 +22,19 @@ REPO=${REPO:?owner/name}
|
|||||||
: "${DIGITALOCEAN_TOKEN:?}" "${GITHUB_TOKEN:?}"
|
: "${DIGITALOCEAN_TOKEN:?}" "${GITHUB_TOKEN:?}"
|
||||||
LABEL=${LABEL:-omarchy-builder}
|
LABEL=${LABEL:-omarchy-builder}
|
||||||
TAG=${TAG:-omarchy-builder}
|
TAG=${TAG:-omarchy-builder}
|
||||||
REGION=${REGION:-ric1}
|
# Sizes to try, in order, in any region DigitalOcean lists them in stock. A
|
||||||
SIZE=${SIZE:-g5-32vcpu-64gb-50gb}
|
# size can sell out in a region for hours; the create is then refused with
|
||||||
|
# 422 and the next region, then the next size, is tried. REGIONS only orders
|
||||||
|
# the regions tried first. SIZE and REGION, if set, are one-item lists.
|
||||||
|
SIZES=${SIZES:-${SIZE:-g5-32vcpu-64gb-50gb g5-32vcpu-128gb-50gb}}
|
||||||
|
REGIONS=${REGIONS:-${REGION:-}}
|
||||||
IMAGE=${IMAGE:-ubuntu-24-04-x64}
|
IMAGE=${IMAGE:-ubuntu-24-04-x64}
|
||||||
MAX_DROPLETS=${MAX_DROPLETS:-4}
|
MAX_DROPLETS=${MAX_DROPLETS:-4}
|
||||||
MAX_AGE_MINUTES=${MAX_AGE_MINUTES:-200}
|
MAX_AGE_MINUTES=${MAX_AGE_MINUTES:-200}
|
||||||
|
# A droplet DigitalOcean still reports as "new" this long after creation is
|
||||||
|
# stuck provisioning. Left alone it counts as a runner booting, and holds a
|
||||||
|
# queued job until MAX_AGE_MINUTES.
|
||||||
|
MAX_BOOT_MINUTES=${MAX_BOOT_MINUTES:-10}
|
||||||
RUNNER_VERSION=${RUNNER_VERSION:-2.337.0}
|
RUNNER_VERSION=${RUNNER_VERSION:-2.337.0}
|
||||||
CLOUD_INIT=${CLOUD_INIT:-$(dirname "$0")/runner-cloud-init.yaml}
|
CLOUD_INIT=${CLOUD_INIT:-$(dirname "$0")/runner-cloud-init.yaml}
|
||||||
# Operator public keys authorized on every builder (JSON array of strings).
|
# Operator public keys authorized on every builder (JSON array of strings).
|
||||||
@@ -39,7 +48,8 @@ log() { echo "$(date '+%F %T') $*"; }
|
|||||||
# both, so every decision below is exercised against canned responses.
|
# both, so every decision below is exercised against canned responses.
|
||||||
do_api() { # do_api <path> [curl args...]
|
do_api() { # do_api <path> [curl args...]
|
||||||
local path=$1; shift
|
local path=$1; shift
|
||||||
curl -fsS -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
|
# --fail-with-body: a refused create still prints why.
|
||||||
|
curl -sS --fail-with-body -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
|
||||||
-H "Content-Type: application/json" "https://api.digitalocean.com/v2/$path" "$@"
|
-H "Content-Type: application/json" "https://api.digitalocean.com/v2/$path" "$@"
|
||||||
}
|
}
|
||||||
gh_api() { # gh_api <path> [curl args...]
|
gh_api() { # gh_api <path> [curl args...]
|
||||||
@@ -55,7 +65,8 @@ reap() {
|
|||||||
while read -r id status created; do
|
while read -r id status created; do
|
||||||
[[ -n "$id" ]] || continue
|
[[ -n "$id" ]] || continue
|
||||||
age=$(( (now - $(date -d "$created" +%s)) / 60 ))
|
age=$(( (now - $(date -d "$created" +%s)) / 60 ))
|
||||||
if [[ $status == off ]] || (( age > MAX_AGE_MINUTES )); then
|
if [[ $status == off ]] || (( age > MAX_AGE_MINUTES )) ||
|
||||||
|
{ [[ $status == new ]] && (( age > MAX_BOOT_MINUTES )); }; then
|
||||||
log "deleting droplet $id (status=$status age=${age}m)"
|
log "deleting droplet $id (status=$status age=${age}m)"
|
||||||
do_api "droplets/$id" -X DELETE
|
do_api "droplets/$id" -X DELETE
|
||||||
fi
|
fi
|
||||||
@@ -64,18 +75,40 @@ reap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# --- demand ----------------------------------------------------------------
|
# --- demand ----------------------------------------------------------------
|
||||||
|
# Emit every item, including later pages of large build matrices. Keep API
|
||||||
|
# failures fatal so a failed query cannot look like an empty queue.
|
||||||
|
gh_items() {
|
||||||
|
local path=$1 key=$2 page=1 response count separator="?"
|
||||||
|
[[ $path != *"?"* ]] || separator="&"
|
||||||
|
while :; do
|
||||||
|
response=$(gh_api "${path}${separator}per_page=100&page=$page") || return 1
|
||||||
|
count=$(jq -er --arg key "$key" '.[$key] | arrays | length' <<< "$response") || return 1
|
||||||
|
jq -c --arg key "$key" '.[$key][]' <<< "$response" || return 1
|
||||||
|
(( count == 100 )) || break
|
||||||
|
((page += 1))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
queued_jobs() {
|
queued_jobs() {
|
||||||
local run
|
local status runs run
|
||||||
gh_api "repos/$REPO/actions/runs?status=queued&per_page=50" --get \
|
# A workflow can be in progress while most of its matrix is still queued.
|
||||||
| jq -r '.workflow_runs[].id' |
|
runs=$(
|
||||||
|
for status in queued in_progress; do
|
||||||
|
gh_items "repos/$REPO/actions/runs?status=$status" workflow_runs || exit 1
|
||||||
|
done
|
||||||
|
) || return 1
|
||||||
|
jq -r '.id' <<< "$runs" | sort -u |
|
||||||
while read -r run; do
|
while read -r run; do
|
||||||
gh_api "repos/$REPO/actions/runs/$run/jobs" \
|
gh_items "repos/$REPO/actions/runs/$run/jobs" jobs |
|
||||||
| jq -r --arg l "$LABEL" '.jobs[] | select(.status=="queued") | select(.labels | index($l)) | .id'
|
jq -r --arg l "$LABEL" 'select(.status=="queued") | select(.labels | index($l)) | .id' || return 1
|
||||||
done | wc -l
|
done | sort -u | wc -l
|
||||||
}
|
}
|
||||||
|
|
||||||
live_droplets() {
|
live_droplets() {
|
||||||
do_api "droplets?tag_name=$TAG&per_page=200" | jq '[.droplets[] | select(.status != "off")] | length'
|
# Not the ones reap() just deleted: DigitalOcean can list them for a while.
|
||||||
|
do_api "droplets?tag_name=$TAG&per_page=200" | jq --argjson boot "$MAX_BOOT_MINUTES" '
|
||||||
|
[.droplets[] | select(.status != "off")
|
||||||
|
| select(.status != "new" or (now - (.created_at | fromdateiso8601)) / 60 <= $boot)] | length'
|
||||||
}
|
}
|
||||||
|
|
||||||
busy_runners() {
|
busy_runners() {
|
||||||
@@ -83,22 +116,59 @@ busy_runners() {
|
|||||||
| jq --arg l "$LABEL" '[.runners[] | select(.busy) | select(any(.labels[]; .name == $l))] | length'
|
| jq --arg l "$LABEL" '[.runners[] | select(.busy) | select(any(.labels[]; .name == $l))] | length'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --- capacity --------------------------------------------------------------
|
||||||
|
# "size region" lines to try, best first: SIZES order, then REGIONS order,
|
||||||
|
# then every other region where DigitalOcean lists the size in stock.
|
||||||
|
candidates() {
|
||||||
|
local page=1 response count catalog=""
|
||||||
|
while :; do
|
||||||
|
response=$(do_api "sizes?per_page=200&page=$page") || return 1
|
||||||
|
count=$(jq -er '.sizes | arrays | length' <<< "$response") || return 1
|
||||||
|
catalog+=$(jq -c '.sizes[]' <<< "$response")$'\n'
|
||||||
|
(( count == 200 )) || break
|
||||||
|
((page += 1))
|
||||||
|
done
|
||||||
|
jq -rs --arg sizes "$SIZES" --arg regions "$REGIONS" '
|
||||||
|
($regions | split(" ") | map(select(length > 0))) as $pref
|
||||||
|
| INDEX(.slug) as $by
|
||||||
|
| $sizes | split(" ") | map(select(length > 0)) | .[]
|
||||||
|
| . as $size | $by[$size] // {} | select(.available == true)
|
||||||
|
| .regions as $in
|
||||||
|
| (($pref | map(select(. as $r | $in | index($r)))) + ($in - $pref))[]
|
||||||
|
| "\($size) \(.)"' <<< "$catalog"
|
||||||
|
}
|
||||||
|
|
||||||
# --- create ----------------------------------------------------------------
|
# --- create ----------------------------------------------------------------
|
||||||
|
# Built once per tick by the first create; a refused pair is dropped from it.
|
||||||
|
CANDIDATES=""
|
||||||
create_droplet() {
|
create_droplet() {
|
||||||
local token userdata name body
|
local token userdata name size region body response
|
||||||
|
[[ -n $CANDIDATES ]] || CANDIDATES=$(candidates) || return 1
|
||||||
token=$(gh_api "repos/$REPO/actions/runners/registration-token" -X POST | jq -r .token)
|
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" \
|
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|__RUNNER_LABELS__|$LABEL|g" -e "s|__RUNNER_VERSION__|$RUNNER_VERSION|g" \
|
||||||
-e "s|__SSH_KEYS_JSON__|$SSH_KEYS_JSON|" "$CLOUD_INIT")
|
-e "s|__SSH_KEYS_JSON__|$SSH_KEYS_JSON|" "$CLOUD_INIT")
|
||||||
name="$TAG-$(date +%s)-$RANDOM"
|
name="$TAG-$(date +%s)-$RANDOM"
|
||||||
body=$(jq -n --arg name "$name" --arg region "$REGION" --arg size "$SIZE" --arg image "$IMAGE" \
|
while read -r size region; do
|
||||||
--arg tag "$TAG" --arg ud "$userdata" \
|
[[ -n $size ]] || continue
|
||||||
'{name:$name, region:$region, size:$size, image:$image, tags:[$tag], user_data:$ud, monitoring:false}')
|
body=$(jq -n --arg name "$name" --arg region "$region" --arg size "$size" --arg image "$IMAGE" \
|
||||||
log "creating $name ($SIZE)"
|
--arg tag "$TAG" --arg ud "$userdata" \
|
||||||
do_api droplets -X POST -d "$body" | jq -r '"created droplet \(.droplet.id)"'
|
'{name:$name, region:$region, size:$size, image:$image, tags:[$tag], user_data:$ud, monitoring:false}')
|
||||||
|
log "creating $name ($size in $region)"
|
||||||
|
if response=$(do_api droplets -X POST -d "$body"); then
|
||||||
|
jq -r '"created droplet \(.droplet.id)"' <<< "$response"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
log "$size in $region refused: $(jq -r .message <<< "$response" 2>/dev/null || echo "$response")"
|
||||||
|
CANDIDATES=$(grep -Fvx "$size $region" <<< "$CANDIDATES" || true)
|
||||||
|
done <<< "$CANDIDATES"
|
||||||
|
# Every size refused everywhere: the rest of this tick's creates would be too.
|
||||||
|
log "no size in '$SIZES' can be created in any region"
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
controller_tick() {
|
controller_tick() {
|
||||||
|
CANDIDATES=""
|
||||||
reap
|
reap
|
||||||
local queued live busy available need room
|
local queued live busy available need room
|
||||||
queued=$(queued_jobs)
|
queued=$(queued_jobs)
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ write_files:
|
|||||||
content: |
|
content: |
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
# Power off after the one job, and also when the download or the
|
||||||
|
# registration fails: the controller deletes powered-off droplets, but
|
||||||
|
# counts a running one as a runner still booting until MAX_AGE_MINUTES.
|
||||||
|
trap 'sudo poweroff' EXIT
|
||||||
cd /home/runner
|
cd /home/runner
|
||||||
mkdir -p actions-runner && cd actions-runner
|
mkdir -p actions-runner && cd actions-runner
|
||||||
arch=$(uname -m); [[ $arch == x86_64 ]] && arch=x64
|
arch=$(uname -m); [[ $arch == x86_64 ]] && arch=x64
|
||||||
@@ -58,8 +62,6 @@ write_files:
|
|||||||
--labels "__RUNNER_LABELS__" \
|
--labels "__RUNNER_LABELS__" \
|
||||||
--replace
|
--replace
|
||||||
./run.sh
|
./run.sh
|
||||||
# One job done. Power off; the controller deletes powered-off droplets.
|
|
||||||
sudo poweroff
|
|
||||||
|
|
||||||
runcmd:
|
runcmd:
|
||||||
# With no account ssh key attached, DO expires root's password, and sshd
|
# With no account ssh key attached, DO expires root's password, and sshd
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ in `origin` and has no effect on release selection.
|
|||||||
| `1password-beta` | debian | [https://downloads.1password.com/linux/debian/amd64/dists/beta/main/binary-amd64/Packages](https://downloads.1password.com/linux/debian/amd64/dists/beta/main/binary-amd64/Packages) |
|
| `1password-beta` | debian | [https://downloads.1password.com/linux/debian/amd64/dists/beta/main/binary-amd64/Packages](https://downloads.1password.com/linux/debian/amd64/dists/beta/main/binary-amd64/Packages) |
|
||||||
| `1password-cli` | json | [https://app-updates.agilebits.com/check/1/0/CLI2/en/0](https://app-updates.agilebits.com/check/1/0/CLI2/en/0) |
|
| `1password-cli` | json | [https://app-updates.agilebits.com/check/1/0/CLI2/en/0](https://app-updates.agilebits.com/check/1/0/CLI2/en/0) |
|
||||||
| `aether` | github | [omacom/aether](https://github.com/omacom/aether) |
|
| `aether` | github | [omacom/aether](https://github.com/omacom/aether) |
|
||||||
| `asusctl` | git_tags | [https://github.com/OpenGamingCollective/asusctl.git](https://github.com/OpenGamingCollective/asusctl.git) |
|
|
||||||
| `basecamp-cli` | github | [basecamp/basecamp-cli](https://github.com/basecamp/basecamp-cli) |
|
| `basecamp-cli` | github | [basecamp/basecamp-cli](https://github.com/basecamp/basecamp-cli) |
|
||||||
| `bun-bin` | github | [oven-sh/bun](https://github.com/oven-sh/bun) |
|
| `bun-bin` | github | [oven-sh/bun](https://github.com/oven-sh/bun) |
|
||||||
| `claude-code` | regex | [https://downloads.claude.ai/claude-code-releases/latest](https://downloads.claude.ai/claude-code-releases/latest) |
|
| `claude-code` | regex | [https://downloads.claude.ai/claude-code-releases/latest](https://downloads.claude.ai/claude-code-releases/latest) |
|
||||||
@@ -162,21 +161,6 @@ in `origin` and has no effect on release selection.
|
|||||||
| `dbxcli-bin` | github | [dropbox/dbxcli](https://github.com/dropbox/dbxcli) |
|
| `dbxcli-bin` | github | [dropbox/dbxcli](https://github.com/dropbox/dbxcli) |
|
||||||
| `dropbox` | redirect | [https://www.dropbox.com/download?plat=lnx.x86_64](https://www.dropbox.com/download?plat=lnx.x86_64) |
|
| `dropbox` | redirect | [https://www.dropbox.com/download?plat=lnx.x86_64](https://www.dropbox.com/download?plat=lnx.x86_64) |
|
||||||
| `dropbox-cli` | regex | [https://linux.dropbox.com/packages/](https://linux.dropbox.com/packages/) |
|
| `dropbox-cli` | regex | [https://linux.dropbox.com/packages/](https://linux.dropbox.com/packages/) |
|
||||||
| `elephant` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-all` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-archlinuxpkgs` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-bluetooth` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-calc` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-clipboard` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-desktopapplications` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-files` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-menus` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-providerlist` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-runner` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-symbols` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-todo` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-unicode` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `elephant-websearch` | github | [abenz1267/elephant](https://github.com/abenz1267/elephant) |
|
|
||||||
| `heroic-games-launcher-bin` | github | [Heroic-Games-Launcher/HeroicGamesLauncher](https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher) |
|
| `heroic-games-launcher-bin` | github | [Heroic-Games-Launcher/HeroicGamesLauncher](https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher) |
|
||||||
| `hyprshade` | pypi | [hyprshade](https://pypi.org/project/hyprshade/) |
|
| `hyprshade` | pypi | [hyprshade](https://pypi.org/project/hyprshade/) |
|
||||||
| `lib32-nvidia-580xx-utils` | regex | [https://download.nvidia.com/XFree86/Linux-x86_64/](https://download.nvidia.com/XFree86/Linux-x86_64/) |
|
| `lib32-nvidia-580xx-utils` | regex | [https://download.nvidia.com/XFree86/Linux-x86_64/](https://download.nvidia.com/XFree86/Linux-x86_64/) |
|
||||||
@@ -213,7 +197,6 @@ in `origin` and has no effect on release selection.
|
|||||||
| `vi` | regex | [https://sources.archlinux.org/other/vi/](https://sources.archlinux.org/other/vi/) |
|
| `vi` | regex | [https://sources.archlinux.org/other/vi/](https://sources.archlinux.org/other/vi/) |
|
||||||
| `visual-studio-code-bin` | json | [https://update.code.visualstudio.com/api/update/linux-deb-x64/stable/latest](https://update.code.visualstudio.com/api/update/linux-deb-x64/stable/latest) |
|
| `visual-studio-code-bin` | json | [https://update.code.visualstudio.com/api/update/linux-deb-x64/stable/latest](https://update.code.visualstudio.com/api/update/linux-deb-x64/stable/latest) |
|
||||||
| `walker` | github | [abenz1267/walker](https://github.com/abenz1267/walker) |
|
| `walker` | github | [abenz1267/walker](https://github.com/abenz1267/walker) |
|
||||||
| `xdg-terminal-exec` | git_tags | [https://gitlab.freedesktop.org/Vladimir-csp/xdg-terminal-exec.git](https://gitlab.freedesktop.org/Vladimir-csp/xdg-terminal-exec.git) |
|
|
||||||
| `xpadneo-dkms` | github | [atar-axis/xpadneo](https://github.com/atar-axis/xpadneo) |
|
| `xpadneo-dkms` | github | [atar-axis/xpadneo](https://github.com/atar-axis/xpadneo) |
|
||||||
| `yaru-icon-theme` | git_tags | [https://github.com/ubuntu/yaru.git](https://github.com/ubuntu/yaru.git) |
|
| `yaru-icon-theme` | git_tags | [https://github.com/ubuntu/yaru.git](https://github.com/ubuntu/yaru.git) |
|
||||||
| `yay` | github | [Jguer/yay](https://github.com/Jguer/yay) |
|
| `yay` | github | [Jguer/yay](https://github.com/Jguer/yay) |
|
||||||
@@ -221,12 +204,10 @@ in `origin` and has no effect on release selection.
|
|||||||
|
|
||||||
## Existing manual holds
|
## Existing manual holds
|
||||||
|
|
||||||
`grok-bot`, `libfprint-git`, `libretro-cap32-git`, `libretro-database-git`, `libretro-fbneo-git`, `libretro-uae-git`, `libretro-vice-git`, `quickshell-git`, `supergfxctl`.
|
`libfprint-git`, `libretro-cap32-git`, `libretro-database-git`, `libretro-fbneo-git`, `libretro-uae-git`, `libretro-vice-git`, `quickshell-git`, `supergfxctl`.
|
||||||
|
|
||||||
These packages were already excluded from automatic AUR updates. The migration preserves that policy.
|
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.
|
|
||||||
|
|
||||||
`m1n1-aurora` and `uboot-asahi` are deliberate holds: Apple Silicon boot code, pinned by hand like `linux-aurora`, and bumped only after a cold boot on the qualification Macs. `m1n1-aurora` pins an aurora-silicon/m1n1 commit plus a local patch. `uboot-asahi` follows asahi-alarm's recipe and patch set (asahi-alarm/PKGBUILDs), which a tag watch on AsahiLinux/u-boot cannot carry.
|
`m1n1-aurora` and `uboot-asahi` are deliberate holds: Apple Silicon boot code, pinned by hand like `linux-aurora`, and bumped only after a cold boot on the qualification Macs. `m1n1-aurora` pins an aurora-silicon/m1n1 commit plus a local patch. `uboot-asahi` follows asahi-alarm's recipe and patch set (asahi-alarm/PKGBUILDs), which a tag watch on AsahiLinux/u-boot cannot carry.
|
||||||
|
|
||||||
`cua-driver-bin` is a deliberate hold: Omarchy bumps it by hand, so a Cua release ships only when a maintainer has verified it. It keeps its `.omarchy/upstream.sh` hook and `min_release_age`, so lifting the hold means removing `"sync": false`. `cua-hyprland-plugin` declares no upstream source, so no automation updates it either.
|
`cua-driver-bin` is a deliberate hold: Omarchy bumps it by hand, so a Cua release ships only when a maintainer has verified it. It keeps its `.omarchy/upstream.sh` hook and `min_release_age`, so lifting the hold means removing `"sync": false`. `cua-hyprland-plugin` declares no upstream source, so no automation updates it either.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ case "${CARCH}" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
pkgver=8.12.40_27.BETA
|
pkgver=8.12.40_27.BETA
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
conflicts=('1password' '1password-beta-bin')
|
conflicts=('1password' '1password-beta-bin')
|
||||||
pkgdesc="Password manager and secure wallet"
|
pkgdesc="Password manager and secure wallet"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
pkgname=1password-cli
|
pkgname=1password-cli
|
||||||
pkgver=2.40.0
|
pkgver=2.40.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="1Password command line tool"
|
pkgdesc="1Password command line tool"
|
||||||
arch=('x86_64' 'i686' 'arm' 'armv6h' 'aarch64')
|
arch=('x86_64' 'i686' 'arm' 'armv6h' 'aarch64')
|
||||||
url="https://app-updates.agilebits.com/product_history/CLI2"
|
url="https://app-updates.agilebits.com/product_history/CLI2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
pkgname=1password
|
pkgname=1password
|
||||||
pkgver=8.12.40
|
pkgver=8.12.40
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
conflicts=('1password-beta' '1password-beta-bin')
|
conflicts=('1password-beta' '1password-beta-bin')
|
||||||
pkgdesc="Password manager and secure wallet"
|
pkgdesc="Password manager and secure wallet"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Bjarne Øverli <bjarne@oever.li>
|
# Maintainer: Bjarne Øverli <bjarne@oever.li>
|
||||||
pkgname=aether
|
pkgname=aether
|
||||||
pkgver=4.32.0
|
pkgver=4.32.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='Desktop theming application - extract colors from wallpapers and apply cohesive themes'
|
pkgdesc='Desktop theming application - extract colors from wallpapers and apply cohesive themes'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url='https://github.com/omacom/aether'
|
url='https://github.com/omacom/aether'
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
[asusctl]
|
|
||||||
source = "git"
|
|
||||||
git = "https://github.com/OpenGamingCollective/asusctl.git"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"git_tags": "https://github.com/OpenGamingCollective/asusctl.git",
|
|
||||||
"pattern": "(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "asusctl",
|
|
||||||
"commit": "b0ec6ca495eb331a684db91b0fe12085a868b632"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../LICENSE
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
# Maintainer: Mahdi Sarikhani <mahdisarikhani@outlook.com>
|
|
||||||
# Contributor: Fabian Bornschein <fabiscafe@archlinux.org>
|
|
||||||
# Contributor: Static_Rocket
|
|
||||||
|
|
||||||
pkgbase=asusctl
|
|
||||||
pkgname=(asusctl rog-control-center)
|
|
||||||
pkgver=6.5.0
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc="Daemon and tools to control your ASUS ROG laptop"
|
|
||||||
arch=('x86_64')
|
|
||||||
url="https://asus-linux.org"
|
|
||||||
license=('MPL-2.0')
|
|
||||||
makedepends=('cargo' 'fontconfig')
|
|
||||||
source=("${pkgbase}-${pkgver}.tar.gz::https://github.com/OpenGamingCollective/asusctl/archive/${pkgver}.tar.gz")
|
|
||||||
b2sums=('4179e08a60f9480b62e41d84faade1f46407140a213ca4d60c8699837a2486bda8e66b4ca43fa06149667d02e3d060c3efd792348f9a93a675f762d6ea2d05f8')
|
|
||||||
|
|
||||||
prepare() {
|
|
||||||
cd "${pkgbase}-${pkgver}"
|
|
||||||
export RUSTUP_TOOLCHAIN=stable
|
|
||||||
cargo fetch --locked --target host-tuple
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "${pkgbase}-${pkgver}"
|
|
||||||
export RUSTUP_TOOLCHAIN=stable
|
|
||||||
export CARGO_TARGET_DIR=target
|
|
||||||
make build
|
|
||||||
}
|
|
||||||
|
|
||||||
package_asusctl() {
|
|
||||||
pkgdesc="An utility for Linux to control many aspects of various ASUS laptops"
|
|
||||||
depends=('glibc' 'libgcc' 'libusb' 'systemd-libs')
|
|
||||||
optdepends=(
|
|
||||||
'acpi_call: fan control'
|
|
||||||
'asusctltray: tray profile switcher'
|
|
||||||
'rog-control-center: graphical user interface for asusctl'
|
|
||||||
'supergfxctl: hybrid GPU control'
|
|
||||||
)
|
|
||||||
install=asusctl.install
|
|
||||||
|
|
||||||
cd "${pkgbase}-${pkgver}"
|
|
||||||
make DESTDIR="${pkgdir}" \
|
|
||||||
install-asusctl \
|
|
||||||
install-asusd \
|
|
||||||
install-asusd_user \
|
|
||||||
install-asus-shutdown \
|
|
||||||
install-data-asusd \
|
|
||||||
install-data-asusd_user
|
|
||||||
}
|
|
||||||
|
|
||||||
package_rog-control-center() {
|
|
||||||
pkgdesc="Graphical user interface for asusctl"
|
|
||||||
depends=('asusctl' 'fontconfig' 'glibc' 'hicolor-icon-theme' 'libgcc' 'systemd-libs')
|
|
||||||
|
|
||||||
cd "${pkgbase}-${pkgver}"
|
|
||||||
make DESTDIR="${pkgdir}" \
|
|
||||||
install-rog_gui \
|
|
||||||
install-data-rog_gui
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
version = 1
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = [
|
|
||||||
"PKGBUILD",
|
|
||||||
"README.md",
|
|
||||||
"keys/**",
|
|
||||||
".SRCINFO",
|
|
||||||
".nvchecker.toml",
|
|
||||||
"*.install",
|
|
||||||
"*.sysusers",
|
|
||||||
"*.tmpfiles",
|
|
||||||
"*.logrotate",
|
|
||||||
"*.pam",
|
|
||||||
"*.service",
|
|
||||||
"*.socket",
|
|
||||||
"*.timer",
|
|
||||||
"*.desktop",
|
|
||||||
"*.hook",
|
|
||||||
]
|
|
||||||
SPDX-FileCopyrightText = "Arch Linux contributors"
|
|
||||||
SPDX-License-Identifier = "0BSD"
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
post_install() {
|
|
||||||
printf ":: asusd provides a service that is activated by an udev rule on\n"
|
|
||||||
printf ":: startup. Please reboot the system or run\n"
|
|
||||||
printf ":: # systemctl start asusd.service\n"
|
|
||||||
printf ":: to make it work.\n"
|
|
||||||
printf ":: See https://github.com/OpenGamingCollective/asusctl#kernel-requirements\n"
|
|
||||||
printf ":: for latest required kernel patches/versions\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
post_upgrade() {
|
|
||||||
if systemctl is-active asusd.service --quiet; then
|
|
||||||
printf ":: asusd service will be restarted…\n"
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart asusd.service
|
|
||||||
fi
|
|
||||||
printf ":: See https://github.com/OpenGamingCollective/asusctl#kernel-requirements\n"
|
|
||||||
printf ":: for latest required kernel patches/versions\n"
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
pkgname=brave-bin
|
pkgname=brave-bin
|
||||||
pkgver=1.96.61
|
pkgver=1.96.61
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
epoch=1
|
epoch=1
|
||||||
pkgdesc='Web browser that blocks ads and trackers by default (binary release)'
|
pkgdesc='Web browser that blocks ads and trackers by default (binary release)'
|
||||||
arch=(x86_64 aarch64)
|
arch=(x86_64 aarch64)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname=brave-origin-bin
|
pkgname=brave-origin-bin
|
||||||
pkgver=1.96.61
|
pkgver=1.96.61
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
epoch=1
|
epoch=1
|
||||||
pkgdesc='The minimalist browser from the makers of Brave (binary release).'
|
pkgdesc='The minimalist browser from the makers of Brave (binary release).'
|
||||||
arch=(x86_64 aarch64)
|
arch=(x86_64 aarch64)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
pkgname=claude-code
|
pkgname=claude-code
|
||||||
pkgver=2.1.291
|
pkgver=2.1.291
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="An agentic coding tool that lives in your terminal"
|
pkgdesc="An agentic coding tool that lives in your terminal"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://github.com/anthropics/claude-code"
|
url="https://github.com/anthropics/claude-code"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
pkgname=claude-desktop
|
pkgname=claude-desktop
|
||||||
pkgver=2.19675.1
|
pkgver=2.19675.1
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Official Claude desktop app with Claude Code"
|
pkgdesc="Official Claude desktop app with Claude Code"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://claude.ai"
|
url="https://claude.ai"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: bjarneo <https://github.com/bjarneo>
|
# Maintainer: bjarneo <https://github.com/bjarneo>
|
||||||
pkgname=cliamp
|
pkgname=cliamp
|
||||||
pkgver=2.3.0
|
pkgver=2.3.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='A retro terminal music player inspired by Winamp 2.x'
|
pkgdesc='A retro terminal music player inspired by Winamp 2.x'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url='https://github.com/bjarneo/cliamp'
|
url='https://github.com/bjarneo/cliamp'
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
pkgname='crush-bin'
|
pkgname='crush-bin'
|
||||||
pkgver=0.97.1
|
pkgver=0.97.1
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='A powerful terminal-based AI assistant for developers, providing intelligent coding assistance directly in your terminal.'
|
pkgdesc='A powerful terminal-based AI assistant for developers, providing intelligent coding assistance directly in your terminal.'
|
||||||
url='https://charm.sh/crush'
|
url='https://charm.sh/crush'
|
||||||
arch=('aarch64' 'armv7h' 'i686' 'x86_64')
|
arch=('aarch64' 'armv7h' 'i686' 'x86_64')
|
||||||
|
|||||||
@@ -19,10 +19,8 @@
|
|||||||
# binary to point at pm.sh, a stand-in that declines and names pacman instead.
|
# binary to point at pm.sh, a stand-in that declines and names pacman instead.
|
||||||
|
|
||||||
pkgname=cua-driver-bin
|
pkgname=cua-driver-bin
|
||||||
# Held at 0.28.2: 0.28.3 and newer break screenshots. Bump by hand once a
|
pkgver=0.33.4
|
||||||
# fixed release is verified.
|
pkgrel=1
|
||||||
pkgver=0.28.2
|
|
||||||
pkgrel=3
|
|
||||||
pkgdesc="Computer-use driver for native GUI apps: accessibility-tree snapshots and input injection"
|
pkgdesc="Computer-use driver for native GUI apps: accessibility-tree snapshots and input injection"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://github.com/trycua/cua"
|
url="https://github.com/trycua/cua"
|
||||||
@@ -49,8 +47,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")
|
source_aarch64=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/cua-driver-rs-${pkgver}-linux-arm64.tar.gz")
|
||||||
sha256sums=('c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9'
|
sha256sums=('c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9'
|
||||||
'c76e251c3ed424200eac52bec35ba534336307fabd83a175ab0b47e2084ab0d8')
|
'c76e251c3ed424200eac52bec35ba534336307fabd83a175ab0b47e2084ab0d8')
|
||||||
sha256sums_x86_64=('8f3e5b669e2bcd98d0eecc64f40640aac77f358b6332a06abc6ee79991620f7d')
|
sha256sums_x86_64=('a4759cc41c00691a345f08abfc28ece79aef41447d27a463ddd8662939fa3378')
|
||||||
sha256sums_aarch64=('cadd7e6b757c3ce50f2b5f6e273c154ea48450fb5fcaff744209b382915eddf5')
|
sha256sums_aarch64=('63a1e858a1a407c44ceb407ad133909b8cddedd713aea3b56d7ccb6db784eb48')
|
||||||
|
|
||||||
case "${CARCH}" in
|
case "${CARCH}" in
|
||||||
x86_64) _platform="linux-x86_64" ;;
|
x86_64) _platform="linux-x86_64" ;;
|
||||||
@@ -72,8 +70,8 @@ prepare() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# In 0.28.1 the URL appears in the updater, the printed reinstall command,
|
# Through 0.33.4 the URL appears in the updater, the printed reinstall
|
||||||
# and two embedded copies of Skills/cua-driver/README.md. Rewrite all four
|
# command, and two embedded copies of Skills/cua-driver/README.md. Rewrite all four
|
||||||
# so the embedded instructions also defer to pacman. Any other count means
|
# so the embedded instructions also defer to pacman. Any other count means
|
||||||
# the release layout changed and needs review before packaging.
|
# the release layout changed and needs review before packaging.
|
||||||
local expected=4 found
|
local expected=4 found
|
||||||
@@ -113,4 +111,5 @@ package() {
|
|||||||
ln -s ../lib/cua-driver/cua-driver "${pkgdir}/usr/bin/cua-driver"
|
ln -s ../lib/cua-driver/cua-driver "${pkgdir}/usr/bin/cua-driver"
|
||||||
|
|
||||||
install -Dm644 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
install -Dm644 "${srcdir}/LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||||
|
install -Dm644 THIRD_PARTY_NOTICES.md "${pkgdir}/usr/share/licenses/${pkgname}/THIRD_PARTY_NOTICES.md"
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Optional Cua Hyprland plugin
|
# Optional Cua Hyprland plugin
|
||||||
|
|
||||||
This package targets **Omarchy x86_64**, with Inkscape `1.4.4-6` and two independent background-input lanes. Release `0.32.0-3` is an edge candidate built from the plugin source published with Driver `0.32.0`, paired with `cua-driver-bin` `0.28.2`. That source carries the independent agent keymaps and compatible Num Lock handling that releases `0.26.1-5` through `0.28.2-2` applied as an Omarchy patch; this release applies a smaller one, `downstream.patch`, so foreground typing keeps working with modifier and Compose remaps (see *Keyboard behavior*) and so that, with its guard active, restarting fcitx5 does not crash Hyprland (see *Input-method popups*). The upstream native qualification below covers older, unpatched source. 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 `0.32.0-3` is an edge candidate built from the plugin source published with Driver `0.32.0`, paired with `cua-driver-bin` `0.33.4`; the plugin sources are unchanged from 0.32.0 through 0.33.4. That source carries the independent agent keymaps and compatible Num Lock handling that releases `0.26.1-5` through `0.28.2-2` applied as an Omarchy patch; this release applies a smaller one, `downstream.patch`, so foreground typing keeps working with modifier and Compose remaps (see *Keyboard behavior*) and so that, with its guard active, restarting fcitx5 does not crash Hyprland (see *Input-method popups*). The upstream native qualification below covers older, unpatched source. 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. The upstream qualification covers the original stable profile; the updated Aquamarine profile needs its own Omabot validation before promotion.
|
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.
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ The plugin is optional. Cua Driver works independently, and installation does no
|
|||||||
|
|
||||||
The package uses the [Driver 0.32.0 plugin source](https://github.com/trycua/cua/releases/tag/cua-driver-rs-v0.32.0). Against the Driver 0.26.1 source the profile kit was qualified with, it adds the keyboard behaviour below ([Cua #3970](https://github.com/trycua/cua/pull/3970), adapted from [#473](https://github.com/omacom/omarchy-pkgs/pull/473)) and gives agent keyboards the user seat's key repeat rate instead of zero ([Cua #4358](https://github.com/trycua/cua/pull/4358)), which crashed single-seat clients such as imv that bound an agent seat ([Cua #4257](https://github.com/trycua/cua/issues/4257)). The input protocol header is unchanged.
|
The package uses the [Driver 0.32.0 plugin source](https://github.com/trycua/cua/releases/tag/cua-driver-rs-v0.32.0). Against the Driver 0.26.1 source the profile kit was qualified with, it adds the keyboard behaviour below ([Cua #3970](https://github.com/trycua/cua/pull/3970), adapted from [#473](https://github.com/omacom/omarchy-pkgs/pull/473)) and gives agent keyboards the user seat's key repeat rate instead of zero ([Cua #4358](https://github.com/trycua/cua/pull/4358)), which crashed single-seat clients such as imv that bound an agent seat ([Cua #4257](https://github.com/trycua/cua/issues/4257)). The input protocol header is unchanged.
|
||||||
|
|
||||||
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. This package pairs with `cua-driver-bin 0.28.2`, which speaks the same input protocol v3 to this source; Driver finds the plugin only through its versioned input socket, not through the plugin's provenance. Discovery protocol v2 is separate. `cua-driver-bin` stays at 0.28.2 because Driver 0.28.3 through 0.32.0 refuse desktop capture on Hyprland with more than one output or with one output away from the origin ([Cua #4161](https://github.com/trycua/cua/issues/4161)), where 0.28.2 captures. This pairing is a changed pairing and requires affected replay before promotion.
|
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. This package pairs with `cua-driver-bin 0.33.4`, which speaks the same input protocol v3 to this source; Driver finds the plugin only through its versioned input socket, not through the plugin's provenance. Discovery protocol v2 is separate. Driver 0.28.3 through 0.33.3 refuse desktop capture on Hyprland with more than one output or with one output away from the origin ([Cua #4161](https://github.com/trycua/cua/issues/4161)); 0.33.4 captures there again ([Cua #4305](https://github.com/trycua/cua/pull/4305)). This pairing is a changed pairing and requires affected replay before promotion.
|
||||||
|
|
||||||
Profile `omarchy-hyprland-0562r4-remaps`, kit tooling `1.1.0`, and package release `3` pin:
|
Profile `omarchy-hyprland-0562r4-remaps`, kit tooling `1.1.0`, and package release `3` pin:
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ Profile `omarchy-hyprland-0562r4-remaps`, kit tooling `1.1.0`, and package relea
|
|||||||
This profile derives from Cua's `omarchy-stable-20260910` profile. Arch's Hyprland `0.56.2-4` is a rebuild of the same 0.56.2 release against vulkan-sdk 1.4.363 and glslang, built with the same GCC `16.2.1 20260810` and linked to the same `libstdc++`. Its executable (SHA-256 `55da553be71222566ee73b973d2f56dbb9939044d8f22f81aa54b66c83f2f6d1`) and two of its 497 headers differ from `-3`: `src/version.h` now names the Aquamarine `0.15.1` and hyprutils `0.14.2` it was built against, and `protocols/hyprland-input-capture-v1.hpp` gains a destroy handler. The header inventory is re-measured the way `profile_verify.py` measures it, giving `1fdefe6ac027a159d04a5dfee4928ec7ebd15544a9a25b5f66d2f5a46fcf364a`; that method reproduces the kit's `-2`/`-3` values exactly.
|
This profile derives from Cua's `omarchy-stable-20260910` profile. Arch's Hyprland `0.56.2-4` is a rebuild of the same 0.56.2 release against vulkan-sdk 1.4.363 and glslang, built with the same GCC `16.2.1 20260810` and linked to the same `libstdc++`. Its executable (SHA-256 `55da553be71222566ee73b973d2f56dbb9939044d8f22f81aa54b66c83f2f6d1`) and two of its 497 headers differ from `-3`: `src/version.h` now names the Aquamarine `0.15.1` and hyprutils `0.14.2` it was built against, and `protocols/hyprland-input-capture-v1.hpp` gains a destroy handler. The header inventory is re-measured the way `profile_verify.py` measures it, giving `1fdefe6ac027a159d04a5dfee4928ec7ebd15544a9a25b5f66d2f5a46fcf364a`; that method reproduces the kit's `-2`/`-3` values exactly.
|
||||||
The checked-in `PROFILE.json` changes only the profile name, package release, source release, exact Hyprland, Aquamarine and glibc package versions, and the re-measured compositor executable and header hashes. Compiler and libstdc++ runtime identities remain Cua's; the separately recorded patch changes the build source. Cua publishes the profile tooling only in the 0.26.1 kit, and the Driver 0.32.0 source manifest has exactly the fields that kit's `profile_verify.py` checks. The download wrapper verifies the original kit and the Driver 0.32.0 source archive before substituting that archive and its manifest into the kit, deriving the updated profile and provenance, and rendering the recipe from the kit's own `PROFILE-PKGBUILD.in`. It then verifies every derived member against its recorded digest, so the result is the kit Cua's `profile_verify.py` accepts as complete for this profile.
|
The checked-in `PROFILE.json` changes only the profile name, package release, source release, exact Hyprland, Aquamarine and glibc package versions, and the re-measured compositor executable and header hashes. Compiler and libstdc++ runtime identities remain Cua's; the separately recorded patch changes the build source. Cua publishes the profile tooling only in the 0.26.1 kit, and the Driver 0.32.0 source manifest has exactly the fields that kit's `profile_verify.py` checks. The download wrapper verifies the original kit and the Driver 0.32.0 source archive before substituting that archive and its manifest into the kit, deriving the updated profile and provenance, and rendering the recipe from the kit's own `PROFILE-PKGBUILD.in`. It then verifies every derived member against its recorded digest, so the result is the kit Cua's `profile_verify.py` accepts as complete for this profile.
|
||||||
|
|
||||||
The native qualification below was recorded with package `0.26.1-2` and Hyprland `-2`. The 0.32.0 source and its Omarchy patch, the Aquamarine and glibc updates, and the Driver 0.28.2 pairing need their own application and Driver replay before promotion. Hyprland `0.56.2-4`, Aquamarine `0.15.1-1` and glibc `2.44+r50+g1848099f063e-1` must all reach a destination channel before this artifact can be installed there; publication still follows edge → RC → stable.
|
The native qualification below was recorded with package `0.26.1-2` and Hyprland `-2`. The 0.32.0 source and its Omarchy patch, the Aquamarine and glibc updates, and the Driver 0.33.4 pairing need their own application and Driver replay before promotion. Hyprland `0.56.2-4`, Aquamarine `0.15.1-1` and glibc `2.44+r50+g1848099f063e-1` must all 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,
|
The generated `PKGBUILD` identifies the immutable kit download, outer checksum,
|
||||||
and member checksums. The kit records the full source and tooling revisions,
|
and member checksums. The kit records the full source and tooling revisions,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname=cursor-bin
|
pkgname=cursor-bin
|
||||||
pkgver=3.23.23
|
pkgver=3.23.23
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='AI-first coding environment'
|
pkgdesc='AI-first coding environment'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://www.cursor.com"
|
url="https://www.cursor.com"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pkgver=2026.10.01.1.e373342
|
|||||||
# Derive the upstream version (YYYY.MM.DD-<hash>) from that pkgver.
|
# Derive the upstream version (YYYY.MM.DD-<hash>) from that pkgver.
|
||||||
_upstream_ver="${pkgver%.*}"
|
_upstream_ver="${pkgver%.*}"
|
||||||
_upstream_ver="${_upstream_ver%.*}-${pkgver##*.}"
|
_upstream_ver="${_upstream_ver%.*}-${pkgver##*.}"
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
# epoch=1: bumped when switching from the original `20250808.0.<sha>` scheme
|
# epoch=1: bumped when switching from the original `20250808.0.<sha>` scheme
|
||||||
# to the current `YYYY.MM.DD.<n>.<hash>` scheme (2025-08-09). Never decrease.
|
# to the current `YYYY.MM.DD.<n>.<hash>` scheme (2025-08-09). Never decrease.
|
||||||
epoch=1
|
epoch=1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
pkgname=disktree-bin
|
pkgname=disktree-bin
|
||||||
_name=disktree
|
_name=disktree
|
||||||
pkgver=0.11.0
|
pkgver=0.11.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Disk space treemap for Omarchy: see what fills a disk by kind, mark what should go, and remove it"
|
pkgdesc="Disk space treemap for Omarchy: see what fills a disk by kind, mark what should go, and remove it"
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://github.com/tobi/disktree"
|
url="https://github.com/tobi/disktree"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
pkgname=dropbox-cli
|
pkgname=dropbox-cli
|
||||||
pkgver=2026.09.28
|
pkgver=2026.09.28
|
||||||
pkgrel=2
|
pkgrel=3
|
||||||
pkgdesc="Command line interface for Dropbox"
|
pkgdesc="Command line interface for Dropbox"
|
||||||
arch=("any")
|
arch=("any")
|
||||||
url="https://www.dropbox.com"
|
url="https://www.dropbox.com"
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-all",
|
|
||||||
"commit": "5614a0a61616643e448fb7c68d58237715ce2739"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-all
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='elephant + all official elephant providers'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
depends=('libqalculate' 'wl-clipboard' 'imagemagick' 'fd' 'wtype' 'jq' 'sqlite3')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant' 'elephant-playerctl' 'elephant-wireplumber' 'elephant-bitwarden' 'elephant-dnfpackages' 'elephant-1password' 'elephant-bookmarks' 'elephant-nirisessions' 'elephant-niriactions' 'elephant-archlinuxpkgs' 'elephant-bluetooth' 'elephant-calc' 'elephant-clipboard' 'elephant-desktopapplications' 'elephant-files' 'elephant-menus' 'elephant-providerlist' 'elephant-runner' 'elephant-snippets' 'elephant-symbols' 'elephant-todo' 'elephant-unicode' 'elephant-websearch' 'elephant-windows')
|
|
||||||
provides=('elephant' 'elephant-playerctl' 'elephant-wireplumber' 'elephant-nirisessions' 'elephant-niriactions' 'elephant-archlinuxpkgs' 'elephant-bluetooth' 'elephant-calc' 'elephant-clipboard' 'elephant-desktopapplications' 'elephant-files' 'elephant-menus' 'elephant-providerlist' 'elephant-runner' 'elephant-snippets' 'elephant-symbols' 'elephant-todo' 'elephant-unicode' 'elephant-websearch' 'elephant-windows')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
# Build main elephant binary
|
|
||||||
cd elephant-${pkgver}/cmd/elephant
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -x -o elephant -trimpath
|
|
||||||
|
|
||||||
# Build all provider plugins
|
|
||||||
cd ../../internal/providers
|
|
||||||
|
|
||||||
# Build each provider
|
|
||||||
for provider in playerctl wireplumber archlinuxpkgs bitwarden dnfpackages 1password bookmarks bluetooth nirisessions niriactions calc clipboard desktopapplications files menus providerlist runner snippets symbols todo unicode websearch windows; do
|
|
||||||
cd $provider
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
cd ..
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
# Install main elephant binary
|
|
||||||
cd elephant-${pkgver}/cmd/elephant
|
|
||||||
install -Dm 755 elephant -t "${pkgdir}/usr/bin"
|
|
||||||
|
|
||||||
# Install all provider plugins
|
|
||||||
cd ../../internal/providers
|
|
||||||
for provider in playerctl wireplumber archlinuxpkgs bitwarden dnfpackages bookmarks 1password nirisessions niriactions bluetooth calc clipboard desktopapplications files menus providerlist runner snippets symbols todo unicode websearch windows; do
|
|
||||||
install -Dm 755 $provider/$provider.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Install license
|
|
||||||
cd ../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-archlinuxpkgs",
|
|
||||||
"commit": "659b81f1aa74a13fd2ebec222e19da2046d8e977"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-archlinuxpkgs
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='archlinuxpkgs provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-archlinuxpkgs')
|
|
||||||
provides=('elephant-archlinuxpkgs')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/archlinuxpkgs
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/archlinuxpkgs
|
|
||||||
install -Dm 755 archlinuxpkgs.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-bluetooth",
|
|
||||||
"commit": "42d9dd5424884c51b8fe6bf7692caf0a31007f05"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-bluetooth
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='bluetooth provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-bluetooth')
|
|
||||||
provides=('elephant-bluetooth')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/bluetooth
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/bluetooth
|
|
||||||
install -Dm 755 bluetooth.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-calc",
|
|
||||||
"commit": "84aba9e90bbd65af45f83168cd6c7bce6ec4322e"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-calc
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='calc provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
depends=('libqalculate')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-calc')
|
|
||||||
provides=('elephant-calc')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/calc
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/calc
|
|
||||||
install -Dm 755 calc.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-clipboard",
|
|
||||||
"commit": "3176f9de1445e7115009383f9cdac116729fc7be"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-clipboard
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='clipboard provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
depends=('wl-clipboard' 'imagemagick')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-clipboard')
|
|
||||||
provides=('elephant-clipboard')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/clipboard
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/clipboard
|
|
||||||
install -Dm 755 clipboard.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-desktopapplications",
|
|
||||||
"commit": "c30e33db5fef912dec9aa157773b10ffab1e0307"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-desktopapplications
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='desktopapplications provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-desktopapplications')
|
|
||||||
provides=('elephant-desktopapplications')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/desktopapplications
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/desktopapplications
|
|
||||||
install -Dm 755 desktopapplications.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-files",
|
|
||||||
"commit": "2d16502b7a905e7d7a03e0026c5519c3b3c4abf2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-files
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='files provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
depends=('fd')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-files')
|
|
||||||
provides=('elephant-files')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/files
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/files
|
|
||||||
install -Dm 755 files.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-menus",
|
|
||||||
"commit": "5ab583fee6ba3e387d49ffe4e409bb84bc60ea24"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-menus
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='menus provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-menus')
|
|
||||||
provides=('elephant-menus')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/menus
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/menus
|
|
||||||
install -Dm 755 menus.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-providerlist",
|
|
||||||
"commit": "1d756a138e926a81b9d33265f0197b8661168845"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-providerlist
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='providerlist provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-providerlist')
|
|
||||||
provides=('elephant-providerlist')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/providerlist
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/providerlist
|
|
||||||
install -Dm 755 providerlist.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-runner",
|
|
||||||
"commit": "e47641530d912199372204cf8780ef37f99f0b37"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-runner
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='runner provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-runner')
|
|
||||||
provides=('elephant-runner')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/runner
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/runner
|
|
||||||
install -Dm 755 runner.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-symbols",
|
|
||||||
"commit": "32263e8b71390ab38b8aa1fd82fc2595b41a5157"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-symbols
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='symbols provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-symbols')
|
|
||||||
provides=('elephant-symbols')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/symbols
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/symbols
|
|
||||||
install -Dm 755 symbols.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-todo",
|
|
||||||
"commit": "447978df5ea3afd1e10959d7973c0b35367724c3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-todo
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='todo provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-todo')
|
|
||||||
provides=('elephant-todo')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/todo
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/todo
|
|
||||||
install -Dm 755 todo.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-unicode",
|
|
||||||
"commit": "23222b0d304a234c74f630c5b9176d58c6c6e0b3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-unicode
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='unicode provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-unicode')
|
|
||||||
provides=('elephant-unicode')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/unicode
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/unicode
|
|
||||||
install -Dm 755 unicode.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant-websearch",
|
|
||||||
"commit": "6b5da831da33e3533593823826a8ffb1a008a299"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant-websearch
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='websearch provider for elephant'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant-websearch')
|
|
||||||
provides=('elephant-websearch')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/websearch
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -buildmode=plugin -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd elephant-${pkgver}/internal/providers/websearch
|
|
||||||
install -Dm 755 websearch.so -t "${pkgdir}/usr/lib/elephant"
|
|
||||||
|
|
||||||
cd ../../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"upstream": {
|
|
||||||
"watch": {
|
|
||||||
"github": "abenz1267/elephant",
|
|
||||||
"pattern": "v(?P<version>[0-9]+(?:\\.[0-9]+)*)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin": {
|
|
||||||
"aur": "elephant",
|
|
||||||
"commit": "6dd02e6987a7a91be6a33e9600147523efa7fa5a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Maintainer: Andrej Benz <hello[at]benz[dot]dev>
|
|
||||||
|
|
||||||
pkgname=elephant
|
|
||||||
pkgver=2.22.1
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='general purpose datasource and executor'
|
|
||||||
url='https://github.com/abenz1267/elephant'
|
|
||||||
arch=('x86_64' 'aarch64')
|
|
||||||
license=('GPL')
|
|
||||||
makedepends=('go')
|
|
||||||
conflicts=('elephant')
|
|
||||||
provides=('elephant')
|
|
||||||
source=("${url}/archive/refs/tags/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('3d1d0d4c55ae531fa3f06406b96504b5165a0d7b53523d1f8351d9d93e457f44')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd ${pkgname}-${pkgver}/cmd/elephant
|
|
||||||
go build -ldflags="-s -w" -buildvcs=false -x -o elephant -trimpath
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd ${pkgname}-${pkgver}/cmd/elephant
|
|
||||||
install -Dm 755 elephant -t "${pkgdir}/usr/bin"
|
|
||||||
|
|
||||||
cd ../../
|
|
||||||
install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname=flea
|
pkgname=flea
|
||||||
pkgver=0.3.7
|
pkgver=0.3.7
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='Fast, keyboard-first file manager for Omarchy'
|
pkgdesc='Fast, keyboard-first file manager for Omarchy'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url='https://github.com/thisisgm/flea'
|
url='https://github.com/thisisgm/flea'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pkgname=github-copilot-cli
|
|||||||
_pkgexec=copilot
|
_pkgexec=copilot
|
||||||
|
|
||||||
pkgver=1.0.92
|
pkgver=1.0.92
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
|
|
||||||
pkgdesc="GitHub Copilot CLI brings the power of Copilot coding agent directly to your terminal."
|
pkgdesc="GitHub Copilot CLI brings the power of Copilot coding agent directly to your terminal."
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
pkgname=google-chrome
|
pkgname=google-chrome
|
||||||
pkgver=155.0.8059.39
|
pkgver=155.0.8059.39
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="The popular web browser by Google (Stable Channel)"
|
pkgdesc="The popular web browser by Google (Stable Channel)"
|
||||||
arch=(
|
arch=(
|
||||||
'x86_64'
|
'x86_64'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"sync": false,
|
"release_ring": "fast",
|
||||||
"origin": {
|
"origin": {
|
||||||
"aur": "grok-bot",
|
"aur": "grok-bot",
|
||||||
"commit": "05eb78fca06b482affda28b26223cbf249d4bbcd"
|
"commit": "05eb78fca06b482affda28b26223cbf249d4bbcd"
|
||||||
|
|||||||
Executable
+84
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Cursor publishes Grok Bot from its own Debian repository, one index per
|
||||||
|
# architecture. Each index carries the version and the SHA256, so an update
|
||||||
|
# is two small HTTP requests instead of downloading the debs, and the pool
|
||||||
|
# URL is keyed by version. bin/sync-upstream can rewrite pkgver and the
|
||||||
|
# checksums; it cannot rewrite a commit id embedded in the old
|
||||||
|
# downloads.cursor.com/grokbot/stable/<commit>/ URL.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_URL="https://downloads.cursor.com/aptrepo"
|
||||||
|
declare -A DEB_ARCHES=([x86_64]=amd64 [aarch64]=arm64)
|
||||||
|
|
||||||
|
# Print "<version> <sha256>" for the newest grok-bot stanza. Newest is
|
||||||
|
# vercmp's opinion, which is the one bin/sync-upstream and pacman both use;
|
||||||
|
# sort -V disagrees with it over versions like 1.0a. The winner's Filename
|
||||||
|
# must be the versioned pool path the PKGBUILD downloads from.
|
||||||
|
newest_release() {
|
||||||
|
local index="$1" debarch="$2"
|
||||||
|
local version sha256 filename best_version="" best_sha256="" best_filename=""
|
||||||
|
|
||||||
|
while read -r version sha256 filename; do
|
||||||
|
[[ -n "$version" && -n "$sha256" ]] || continue
|
||||||
|
if [[ -z "$best_version" ]] || [[ "$(vercmp "$version" "$best_version")" -gt 0 ]]; then
|
||||||
|
best_version="$version"
|
||||||
|
best_sha256="$sha256"
|
||||||
|
best_filename="$filename"
|
||||||
|
fi
|
||||||
|
done < <(awk '
|
||||||
|
{ sub(/\r$/, "") }
|
||||||
|
/^Package:/ { package = $2 }
|
||||||
|
/^Version:/ { version = $2 }
|
||||||
|
/^SHA256:/ { sha256 = $2 }
|
||||||
|
/^Filename:/ { filename = $2 }
|
||||||
|
/^$/ {
|
||||||
|
if (package == "grok-bot" && version && sha256) print version, sha256, filename
|
||||||
|
package = version = sha256 = filename = ""
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (package == "grok-bot" && version && sha256) print version, sha256, filename
|
||||||
|
}
|
||||||
|
' <<<"$index")
|
||||||
|
|
||||||
|
[[ -n "$best_version" ]] || return 1
|
||||||
|
|
||||||
|
local expected="pool/grok-bot/g/gr/grok-bot_${best_version}_${debarch}.deb"
|
||||||
|
if [[ "$best_filename" != "$expected" ]]; then
|
||||||
|
echo "Unexpected Grok Bot $best_version $debarch Filename: '${best_filename}' (expected $expected)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$best_version $best_sha256"
|
||||||
|
}
|
||||||
|
|
||||||
|
versions=()
|
||||||
|
declare -A checksums=()
|
||||||
|
|
||||||
|
for arch in "${!DEB_ARCHES[@]}"; do
|
||||||
|
index=$(curl -fsSL "$BASE_URL/dists/grok-bot/main/binary-${DEB_ARCHES[$arch]}/Packages")
|
||||||
|
|
||||||
|
read -r version sha256 <<<"$(newest_release "$index" "${DEB_ARCHES[$arch]}")"
|
||||||
|
if [[ -z "${version:-}" || -z "${sha256:-}" ]]; then
|
||||||
|
echo "No usable Grok Bot release found for $arch" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
versions+=("$version")
|
||||||
|
checksums[$arch]="$sha256"
|
||||||
|
done
|
||||||
|
|
||||||
|
# A release can land one architecture at a time. Wait until both agree so one
|
||||||
|
# pkgver always describes both artifacts.
|
||||||
|
for version in "${versions[@]}"; do
|
||||||
|
if [[ "$version" != "${versions[0]}" ]]; then
|
||||||
|
echo "Upstream architectures are mid-release (${versions[*]}); skipping" >&2
|
||||||
|
echo '{}'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
jq -n \
|
||||||
|
--arg pkgver "${versions[0]}" \
|
||||||
|
--arg x86_64 "${checksums[x86_64]}" \
|
||||||
|
--arg aarch64 "${checksums[aarch64]}" \
|
||||||
|
'{pkgver: $pkgver, sha256sums: {x86_64: [$x86_64], aarch64: [$aarch64]}}'
|
||||||
@@ -2,9 +2,8 @@
|
|||||||
# Contributor: Omarchy
|
# Contributor: Omarchy
|
||||||
|
|
||||||
pkgname=grok-bot
|
pkgname=grok-bot
|
||||||
pkgver=0.47.0
|
pkgver=0.68.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
_commit=c1e7d7a46549956d25f53e9c0b9f59666e03aa3a
|
|
||||||
pkgdesc='Grok Bot desktop agent'
|
pkgdesc='Grok Bot desktop agent'
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url='https://x.ai/bot'
|
url='https://x.ai/bot'
|
||||||
@@ -30,20 +29,23 @@ install=grok-bot.install
|
|||||||
|
|
||||||
_deb_x86_64="grok-bot_${pkgver}_amd64.deb"
|
_deb_x86_64="grok-bot_${pkgver}_amd64.deb"
|
||||||
_deb_aarch64="grok-bot_${pkgver}_arm64.deb"
|
_deb_aarch64="grok-bot_${pkgver}_arm64.deb"
|
||||||
|
# Versioned pool paths — Packages indexes carry SHA256 so upstream.sh
|
||||||
|
# can bump pkgver without embedding a Cursor commit id.
|
||||||
|
_pool="https://downloads.cursor.com/aptrepo/pool/grok-bot/g/gr"
|
||||||
source=(
|
source=(
|
||||||
'grok-bot.sh'
|
'grok-bot.sh'
|
||||||
'grok-bot.desktop'
|
'grok-bot.desktop'
|
||||||
)
|
)
|
||||||
source_x86_64=(
|
source_x86_64=(
|
||||||
"${_deb_x86_64}::https://downloads.cursor.com/grokbot/stable/${_commit}/linux/x64/${_deb_x86_64}"
|
"${_deb_x86_64}::${_pool}/${_deb_x86_64}"
|
||||||
)
|
)
|
||||||
source_aarch64=(
|
source_aarch64=(
|
||||||
"${_deb_aarch64}::https://downloads.cursor.com/grokbot/stable/${_commit}/linux/arm64/${_deb_aarch64}"
|
"${_deb_aarch64}::${_pool}/${_deb_aarch64}"
|
||||||
)
|
)
|
||||||
sha256sums=('6dfa6c305941afa6cbaefbeaae06d05ab5a88f31630005d25a819a160c20c7a3'
|
sha256sums=('6dfa6c305941afa6cbaefbeaae06d05ab5a88f31630005d25a819a160c20c7a3'
|
||||||
'3e2a2461ea58d17ac1777616be9ba660f7cb9ceefa9292016e36c55758bf78dd')
|
'3e2a2461ea58d17ac1777616be9ba660f7cb9ceefa9292016e36c55758bf78dd')
|
||||||
sha256sums_x86_64=('11ca0f51a535b97af51a352adf9c0f9ecd2e1b0430a69ae9451b688a7a065808')
|
sha256sums_x86_64=('b2be8106d2b3eae07d983d5f1ca77b657accde666dc440db2a409421ecff3359')
|
||||||
sha256sums_aarch64=('836f8d19d3826c6573c31ac45c7a9b797abc73381ae0d2b1e7a8dae5410e7e46')
|
sha256sums_aarch64=('3f85fbe2ba3c1d122aa16f8be672076bc19146e07e9d431f37a93b85fa75a93f')
|
||||||
noextract=("${_deb_x86_64}" "${_deb_aarch64}")
|
noextract=("${_deb_x86_64}" "${_deb_aarch64}")
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Resolve current Grok Bot stable from Cursor's update feed and pin PKGBUILD.
|
|
||||||
# Linux has no latest alias (linux-x64 feed returns 204). The darwin-arm64
|
|
||||||
# sand feed publishes version + commit; the Linux .deb lives at the same commit.
|
|
||||||
# Darwin can ship first — HEAD-check the Linux URL and fail loudly if 404.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
PKGBUILD_PATH="${1:-PKGBUILD}"
|
|
||||||
[[ -f "${PKGBUILD_PATH}" ]] || { echo "Error: PKGBUILD not found at '${PKGBUILD_PATH}'" >&2; exit 1; }
|
|
||||||
|
|
||||||
FEED='https://api2.cursor.sh/updates/api/update/darwin-arm64/sand/0.0.0/00000000-0000-0000-0000-000000000000/stable'
|
|
||||||
json="$(curl -fsSL -H 'cache-control: no-cache' "${FEED}")"
|
|
||||||
|
|
||||||
ver="$(jq -er '.name // .version' <<<"${json}")"
|
|
||||||
feed_url="$(jq -er '.url' <<<"${json}")"
|
|
||||||
commit="$(sed -nE 's@.*/(grokbot|sand)/stable/([0-9a-f]{40})/.*@\2@p' <<<"${feed_url}")"
|
|
||||||
|
|
||||||
[[ -n "${ver}" && -n "${commit}" ]] || {
|
|
||||||
echo "Error: could not parse version/commit from feed: ${json}" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
deb_url="https://downloads.cursor.com/grokbot/stable/${commit}/linux/x64/Grok_Bot_${ver}.deb"
|
|
||||||
code="$(curl -fsSIL -o /dev/null -w '%{http_code}' "${deb_url}")"
|
|
||||||
[[ "${code}" == "200" ]] || {
|
|
||||||
echo "Error: Linux deb not fetchable (${code}): ${deb_url}" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp="$(mktemp)"
|
|
||||||
trap 'rm -f "${tmp}"' EXIT
|
|
||||||
curl -fL --retry 3 -o "${tmp}" "${deb_url}"
|
|
||||||
sum="$(sha256sum "${tmp}" | awk '{print $1}')"
|
|
||||||
|
|
||||||
current_ver="$(sed -nE 's/^pkgver=([^[:space:]#]+).*/\1/p' "${PKGBUILD_PATH}" | head -n1)"
|
|
||||||
|
|
||||||
sed -i -E \
|
|
||||||
-e "s/^_commit=.*/_commit=${commit}/" \
|
|
||||||
-e "s/^pkgver=.*/pkgver=${ver}/" \
|
|
||||||
-e "0,/^[[:space:]]*'[0-9a-f]{64}'/s// '${sum}'/" \
|
|
||||||
"${PKGBUILD_PATH}"
|
|
||||||
|
|
||||||
if [[ "${ver}" != "${current_ver}" ]]; then
|
|
||||||
sed -i -E 's/^pkgrel=.*/pkgrel=1/' "${PKGBUILD_PATH}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "${ver} ${commit}"
|
|
||||||
echo "${deb_url}"
|
|
||||||
echo "${sum}"
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
pkgname=hermes-desktop
|
pkgname=hermes-desktop
|
||||||
pkgver=2026.9.7
|
pkgver=2026.9.7
|
||||||
pkgrel=3
|
pkgrel=4
|
||||||
pkgdesc='Native desktop shell for Hermes Agent'
|
pkgdesc='Native desktop shell for Hermes Agent'
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
url='https://github.com/NousResearch/hermes-agent'
|
url='https://github.com/NousResearch/hermes-agent'
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"release_ring": "fast",
|
|
||||||
"upstream": {
|
|
||||||
"git_tags": "https://github.com/hyprwm/hyprland-guiutils.git",
|
|
||||||
"tag_pattern": "v{pkgver}",
|
|
||||||
"sources": {
|
|
||||||
"any": [
|
|
||||||
"https://github.com/hyprwm/hyprland-guiutils/archive/v{pkgver}/hyprland-guiutils-{pkgver}.tar.gz"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rebuild_on": [
|
|
||||||
"aquamarine"
|
|
||||||
],
|
|
||||||
"rebuilt_against": {
|
|
||||||
"aarch64": {
|
|
||||||
"aquamarine": "0.15.0-2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Maintainer: Caleb Maclennan <caleb@alerque.com>
|
|
||||||
|
|
||||||
pkgname=hyprland-guiutils
|
|
||||||
pkgver=0.2.2
|
|
||||||
pkgrel=3
|
|
||||||
pkgdesc='Hyprland GUI utilities'
|
|
||||||
arch=(aarch64)
|
|
||||||
url="https://github.com/hyprwm/$pkgname"
|
|
||||||
license=(BSD-3-Clause)
|
|
||||||
depends=(
|
|
||||||
libgcc
|
|
||||||
libstdc++
|
|
||||||
glibc # libc.so libm.so
|
|
||||||
hyprlang
|
|
||||||
hyprtoolkit libhyprtoolkit.so
|
|
||||||
hyprutils libhyprutils.so
|
|
||||||
libdrm
|
|
||||||
pixman
|
|
||||||
)
|
|
||||||
makedepends=(cmake)
|
|
||||||
replaces=(hyprland-qtutils)
|
|
||||||
_archive="$pkgname-$pkgver"
|
|
||||||
source=("$url/archive/v$pkgver/$_archive.tar.gz")
|
|
||||||
sha256sums=('16f92a6c5a22ac58e1fc313f6b202c188da45e804e1f21ff57dfd0da5c1a01b7')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "$_archive"
|
|
||||||
local cmake_flags=(
|
|
||||||
-D CMAKE_BUILD_TYPE=Release
|
|
||||||
-D CMAKE_INSTALL_PREFIX=/usr
|
|
||||||
)
|
|
||||||
cmake -B build ${cmake_flags[@]}
|
|
||||||
cmake --build build
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$_archive"
|
|
||||||
DESTDIR="$pkgdir" cmake --install build
|
|
||||||
install -Dm0644 -t "$pkgdir/usr/share/licenses/$pkgname" LICENSE
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname="hyprland-preview-share-picker"
|
pkgname="hyprland-preview-share-picker"
|
||||||
pkgver=0.2.1
|
pkgver=0.2.1
|
||||||
pkgrel=2
|
pkgrel=3
|
||||||
pkgdesc="An alternative share picker for hyprland with window and monitor previews"
|
pkgdesc="An alternative share picker for hyprland with window and monitor previews"
|
||||||
arch=(x86_64 aarch64)
|
arch=(x86_64 aarch64)
|
||||||
url="https://github.com/WhySoBad/hyprland-preview-share-picker"
|
url="https://github.com/WhySoBad/hyprland-preview-share-picker"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
],
|
],
|
||||||
"rebuilt_against": {
|
"rebuilt_against": {
|
||||||
"aarch64": {
|
"aarch64": {
|
||||||
"aquamarine": "0.15.0-2"
|
"aquamarine": "0.15.1-1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
pkgname=(hyprland hyprpm)
|
pkgname=(hyprland hyprpm)
|
||||||
pkgver=0.56.2
|
pkgver=0.56.2
|
||||||
pkgrel=4
|
pkgrel=5
|
||||||
pkgdesc='a highly customizable dynamic tiling Wayland compositor'
|
pkgdesc='a highly customizable dynamic tiling Wayland compositor'
|
||||||
arch=(aarch64)
|
arch=(aarch64)
|
||||||
url="https://github.com/hyprwm/${pkgname^}"
|
url="https://github.com/hyprwm/${pkgname^}"
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"release_ring": "fast",
|
|
||||||
"upstream": {
|
|
||||||
"git_tags": "https://github.com/hyprwm/hyprtoolkit.git",
|
|
||||||
"tag_pattern": "v{pkgver}",
|
|
||||||
"sources": {
|
|
||||||
"any": [
|
|
||||||
"https://github.com/hyprwm/hyprtoolkit/archive/v{pkgver}/hyprtoolkit-{pkgver}.tar.gz"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rebuild_on": [
|
|
||||||
"aquamarine"
|
|
||||||
],
|
|
||||||
"rebuilt_against": {
|
|
||||||
"aarch64": {
|
|
||||||
"aquamarine": "0.15.0-2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# Maintainer: Caleb Maclennan <caleb@alerque.com>
|
|
||||||
|
|
||||||
pkgname=hyprtoolkit
|
|
||||||
pkgver=0.6.0
|
|
||||||
pkgrel=1
|
|
||||||
pkgdesc='A modern C++ Wayland-native GUI toolkit'
|
|
||||||
arch=(aarch64)
|
|
||||||
url="https://github.com/hyprwm/$pkgname"
|
|
||||||
license=(BSD-3-Clause)
|
|
||||||
depends=(
|
|
||||||
libgcc
|
|
||||||
libstdc++
|
|
||||||
aquamarine libaquamarine.so
|
|
||||||
cairo libcairo.so
|
|
||||||
glib2 libglib-2.0.so
|
|
||||||
glibc # libc.so libm.so
|
|
||||||
hyprgraphics libhyprgraphics.so
|
|
||||||
hyprlang libhyprlang.so
|
|
||||||
hyprutils libhyprutils.so
|
|
||||||
iniparser libiniparser.so
|
|
||||||
libdrm # libdrm.so
|
|
||||||
libglvnd libEGL.so libOpenGL.so
|
|
||||||
libxkbcommon libxkbcommon.so
|
|
||||||
mesa # libgbm.so
|
|
||||||
pango libpango-1.0.so # libpango.so
|
|
||||||
pixman libpixman-1.so
|
|
||||||
wayland libwayland-client.so
|
|
||||||
)
|
|
||||||
makedepends=(cmake
|
|
||||||
hyprwayland-scanner)
|
|
||||||
provides=(libhyprtoolkit.so)
|
|
||||||
_archive="$pkgname-$pkgver"
|
|
||||||
source=("$url/archive/v$pkgver/$_archive.tar.gz")
|
|
||||||
sha256sums=('53c41be72af97d9ede274a63c9c1034c58726d862905763ed6e5a564ae42ba6b')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "$_archive"
|
|
||||||
local cmake_options=(
|
|
||||||
-D CMAKE_BUILD_TYPE=None
|
|
||||||
-D CMAKE_INSTALL_PREFIX=/usr
|
|
||||||
)
|
|
||||||
cmake -B build -W no-dev ${cmake_options[@]}
|
|
||||||
cmake --build build
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$_archive"
|
|
||||||
DESTDIR="$pkgdir" cmake --install build
|
|
||||||
install -Dm0644 -t "$pkgdir/usr/share/licenses/$pkgname/" LICENSE
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname=learn-omarchy
|
pkgname=learn-omarchy
|
||||||
pkgver=0.2.5
|
pkgver=0.2.5
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Interactive, theme-aware courses for learning Omarchy"
|
pkgdesc="Interactive, theme-aware courses for learning Omarchy"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://github.com/DanWahlin/learn-omarchy"
|
url="https://github.com/DanWahlin/learn-omarchy"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
pkgname=libfprint-git
|
pkgname=libfprint-git
|
||||||
pkgver=1.94.100.r10.g6f9479c
|
pkgver=1.94.100.r10.g6f9479c
|
||||||
pkgrel=2
|
pkgrel=3
|
||||||
# Retain the epoch used to supersede the previously published untested build.
|
# Retain the epoch used to supersede the previously published untested build.
|
||||||
epoch=1
|
epoch=1
|
||||||
pkgdesc="Library for fingerprint readers (pinned upstream snapshot with FocalTech and Synaptics 06cb:010b support, and Apple Touch ID on aarch64)"
|
pkgdesc="Library for fingerprint readers (pinned upstream snapshot with FocalTech and Synaptics 06cb:010b support, and Apple Touch ID on aarch64)"
|
||||||
|
|||||||
@@ -8,5 +8,10 @@
|
|||||||
},
|
},
|
||||||
"rebuild_on": [
|
"rebuild_on": [
|
||||||
"libva"
|
"libva"
|
||||||
]
|
],
|
||||||
|
"rebuilt_against": {
|
||||||
|
"aarch64": {
|
||||||
|
"libva": "2.24.1-1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
_fork=sofus13
|
_fork=sofus13
|
||||||
pkgname=libva-v4l2_request-avd
|
pkgname=libva-v4l2_request-avd
|
||||||
pkgver=1.3
|
pkgver=1.3
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc='VA-API driver for V4L2 stateless decoders, with Apple Video Decoder (AVD) support'
|
pkgdesc='VA-API driver for V4L2 stateless decoders, with Apple Video Decoder (AVD) support'
|
||||||
arch=('aarch64')
|
arch=('aarch64')
|
||||||
url="https://github.com/$_fork/libva-v4l2_request"
|
url="https://github.com/$_fork/libva-v4l2_request"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ _pkgname="limine-entry-tool"
|
|||||||
pkgname="limine-mkinitcpio-hook"
|
pkgname="limine-mkinitcpio-hook"
|
||||||
_gradle_version=9.7.1
|
_gradle_version=9.7.1
|
||||||
pkgver=1.40.0
|
pkgver=1.40.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Install kernels for the Limine bootloader."
|
pkgdesc="Install kernels for the Limine bootloader."
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://gitlab.com/Zesko/limine-entry-tool"
|
url="https://gitlab.com/Zesko/limine-entry-tool"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Zesko
|
# Maintainer: Zesko
|
||||||
pkgname="limine-snapper-sync"
|
pkgname="limine-snapper-sync"
|
||||||
pkgver=1.32.1
|
pkgver=1.32.1
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
_gradle_version=9.7.1
|
_gradle_version=9.7.1
|
||||||
pkgdesc="Integrates Limine boot entries with Snapper snapshots."
|
pkgdesc="Integrates Limine boot entries with Snapper snapshots."
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
pkgname=linux-firmware-cirrus-dx13260
|
pkgname=linux-firmware-cirrus-dx13260
|
||||||
pkgver=20260810
|
pkgver=20260810
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Cirrus speaker firmware aliases for Dell XPS 13 DX13260 Panther Lake"
|
pkgdesc="Cirrus speaker firmware aliases for Dell XPS 13 DX13260 Panther Lake"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
url="https://gitlab.com/kernel-firmware/linux-firmware"
|
url="https://gitlab.com/kernel-firmware/linux-firmware"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"source": "local",
|
|
||||||
"release_ring": "fast",
|
|
||||||
"sync": false
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
# 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
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
-----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,4 @@
|
|||||||
|
{
|
||||||
|
"source": "local",
|
||||||
|
"skip_build": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||||
|
--- a/kernel/fork.c
|
||||||
|
+++ b/kernel/fork.c
|
||||||
|
@@ -127,6 +127,12 @@
|
||||||
|
|
||||||
|
#include <kunit/visibility.h>
|
||||||
|
|
||||||
|
+#ifdef CONFIG_USER_NS
|
||||||
|
+static int unprivileged_userns_clone = 1;
|
||||||
|
+#else
|
||||||
|
+#define unprivileged_userns_clone 1
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Minimum number of threads to boot the kernel
|
||||||
|
*/
|
||||||
|
@@ -2092,6 +2098,11 @@ __latent_entropy struct task_struct *copy_process(
|
||||||
|
return ERR_PTR(-EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
|
||||||
|
+ if (!capable(CAP_SYS_ADMIN))
|
||||||
|
+ return ERR_PTR(-EPERM);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Force any signals received before this point to be delivered
|
||||||
|
* before the fork happens. Collect up signals sent to multiple
|
||||||
|
@@ -3165,6 +3176,10 @@ static int check_unshare_flags(unsigned long unshare_flags)
|
||||||
|
if (!current_is_single_threaded())
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
+ if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
|
||||||
|
+ if (!capable(CAP_SYS_ADMIN))
|
||||||
|
+ return -EPERM;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -3400,6 +3415,15 @@ static const struct ctl_table fork_sysctl_table[] = {
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = sysctl_max_threads,
|
||||||
|
},
|
||||||
|
+#ifdef CONFIG_USER_NS
|
||||||
|
+ {
|
||||||
|
+ .procname = "unprivileged_userns_clone",
|
||||||
|
+ .data = &unprivileged_userns_clone,
|
||||||
|
+ .maxlen = sizeof(int),
|
||||||
|
+ .mode = 0644,
|
||||||
|
+ .proc_handler = proc_dointvec,
|
||||||
|
+ },
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init init_fork_sysctl(void)
|
||||||
Binary file not shown.
@@ -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.
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Loaded 100 of 479 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user