Skip to content

Add AUR packaging workflow#414

Closed
akshaynexus wants to merge 7 commits into
ilysenko:mainfrom
akshaynexus:arch-aur
Closed

Add AUR packaging workflow#414
akshaynexus wants to merge 7 commits into
ilysenko:mainfrom
akshaynexus:arch-aur

Conversation

@akshaynexus

@akshaynexus akshaynexus commented Jun 5, 2026

Copy link
Copy Markdown

Summary

Adds an AUR packaging path alongside the existing local pacman package builder.

  • Adds an AUR PKGBUILD template and install hook for codex-desktop-linux
  • Adds scripts/aur/render-aur-package.sh plus make aur and make aur-srcinfo
  • Adds a manual GitHub Actions workflow to render, validate, and optionally publish AUR metadata
  • Declares the managed Node, Electron, and Browser Use runtime archives as AUR sources and passes them into the existing installer through local-source overrides
  • Documents local AUR testing and post-merge publishing setup
  • Extends CI shell syntax checks to cover the new renderer

Closes #402

The AUR package builds from the upstream repository source URL, https://github.com/ilysenko/codex-desktop-linux. This PR does not change codex-update-manager; it only omits the updater from the AUR package payload so Arch users update through pacman/AUR helpers instead.

How maintainers publish to AUR after merge

Publishing is not automatic until the workflow is run manually with publish=true.

  1. Create the AUR package repository once, if it does not already exist:

    git clone ssh://aur@aur.archlinux.org/codex-desktop-linux.git

    The first successful workflow push can populate the empty AUR Git repository with PKGBUILD, .SRCINFO, and codex-desktop-linux.install.

  2. Add an SSH private key that can push to the AUR package as the AUR_SSH_PRIVATE_KEY GitHub Actions secret. The matching public key must be registered on the maintainer's AUR account.

  3. Optionally add AUR_KNOWN_HOSTS. If omitted, the workflow runs ssh-keyscan aur.archlinux.org during setup.

  4. Open GitHub Actions in this repository and run Publish AUR Package manually with publish set to true.

  5. Optionally set pkgver for a specific package version. If omitted, the workflow uses a UTC timestamp in YYYY.MM.DD.HHMMSS format.

  6. Optionally set source_ref for a specific commit, tag, or branch. If omitted, the workflow uses the workflow run's commit SHA. The workflow resolves this value to a full commit SHA before rendering PKGBUILD.

The workflow keeps the GitHub source archive and DMG checksums as SKIP, while computing checksums for declared runtime archives when publish=true. GitHub-generated source archives can be regenerated with different compressed bytes, and the Codex DMG is consumed from the stable upstream download URL. Package freshness is handled by rerunning the publish workflow for a new AUR revision.

The AUR build now declares the large runtime archives that already have installer override hooks: managed Node, Electron, and Browser Use node_repl on x86_64. The remaining networked part is npm rebuild inputs for native modules; making those source-declared would require a larger npm/cache mode outside this PR.

Validation

  • bash -n install.sh
  • bash -n scripts/aur/render-aur-package.sh
  • make aur-srcinfo AUR_PKGVER=2026.06.05
  • AUR_SOURCE_REF=refs/tags/v1 AUR_PKGVER=2026.06.05 ./scripts/aur/render-aur-package.sh fails with the expected full-SHA validation error
  • Full local AUR-style build with makepkg -si --needed --noconfirm
  • Installed resulting package with pacman -U dist/aur/codex-desktop-linux-2026.06.05-1-x86_64.pkg.tar.zst after removing the previous codex-desktop package

@akshaynexus akshaynexus marked this pull request as ready for review June 5, 2026 04:08

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f967f2eb5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/aur.yml Outdated

AUR_DIR=/work/dist/aur ./scripts/aur/render-aur-package.sh
cd /work/dist/aur
makepkg --printsrcinfo > .SRCINFO

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Run makepkg as a non-root user

In this workflow the Arch container is started without --user, so this makepkg --printsrcinfo runs as UID 0. Arch's makepkg documentation lists --printsrcinfo as a makepkg mode and documents exit code 10 for "User attempted to run makepkg as root" (https://man.archlinux.org/man/makepkg.8.en), so every manual AUR workflow dispatch will fail here before uploading or publishing the rendered package files. Create/chown a build user in the container and run makepkg under that user.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/aur.yml Outdated

if [ "${AUR_PUBLISH:-false}" = "true" ]; then
archive_url="${AUR_SOURCE_REPO}/archive/${AUR_SOURCE_REF}.tar.gz"
AUR_SOURCE_SHA256="$(curl -fsSL "$archive_url" | sha256sum | cut -d" " -f1)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid hashing GitHub's generated tarball bytes

When publish=true, this records the checksum of GitHub's generated .tar.gz bytes in the AUR sha256sums. GitHub documents that source archives are generated on request/cache and that the same archive content can later be served with a different compressed byte layout (https://docs.github.com/repositories/working-with-files/using-files/downloading-source-code-archives), so once GitHub regenerates this archive, makepkg will reject the source before the package can build even though the commit is unchanged. Use a VCS source, SKIP for this generated archive, or a stable release asset instead.

Useful? React with 👍 / 👎.


_source_ref="__SOURCE_REF__"
_dmg_url="__DMG_URL__"
_repo_dir="codex-desktop-linux-${_source_ref}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Sanitize slash-containing source refs

If the source_ref input is a normal fully qualified Git ref such as refs/tags/v1.0 or a branch name containing /, this embeds the slash into _repo_dir, and the later cd "${srcdir}/${_repo_dir}" expects nested directories that GitHub's archive extraction will not create for that ref. That breaks the advertised "Git ref or commit" override; resolve the input to a commit or derive the extracted directory name independently from the raw ref.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/aur.yml
- name: Render and validate in Arch Linux
run: |
set -euo pipefail
docker run --rm \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve mutable refs before publishing

Because this accepts source_ref as a generic Git ref and writes it unchanged into the published PKGBUILD, choosing a branch such as main publishes a package whose checksum was computed for the branch at dispatch time but whose source URL will fetch the branch's later contents after it advances. In that scenario AUR users hit a checksum failure even though the workflow succeeded; resolve any input ref to an immutable commit SHA before rendering and hashing the package.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1679f80115

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/aur.yml Outdated
fi

if [ "${AUR_PUBLISH:-false}" = "true" ]; then
AUR_DMG_SHA256="$(curl -fL --retry 3 "$AUR_DMG_URL" | sha256sum | cut -d" " -f1)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid pinning the rolling DMG checksum

When publish=true, this records a checksum for AUR_DMG_URL, but the rendered PKGBUILD still downloads the same rolling https://persistent.oaistatic.com/codex-app-prod/Codex.dmg later. This repo already treats that DMG as mutable via the Nix hash refresh flow, so after upstream replaces the DMG, AUR users building the last published package will fail checksum validation until this workflow is rerun; publish an immutable DMG URL/asset or intentionally use SKIP with another integrity mechanism.

Useful? React with 👍 / 👎.

export CODEX_LINUX_SOURCE_BRANCH=""
export CODEX_LINUX_SOURCE_DESCRIBE="${pkgver}-${pkgrel}"

./install.sh "${srcdir}/Codex.dmg"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include install.sh downloads in AUR sources

In makepkg environments that fetch sources first and build later without network access, this ./install.sh step still downloads the managed Node runtime, Electron runtime, and npm packages, but none of those inputs are listed in source/sha256sums. That makes the AUR package non-reproducible and unable to build from the declared source set; add these archives/packages to the PKGBUILD sources or provide a source-only/cache mode that install.sh uses during AUR builds.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/aur.yml Outdated
cd /tmp/aur-codex-desktop-linux
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet -- PKGBUILD .SRCINFO *.install; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect untracked files before skipping publish

When the AUR repository is empty, the copied PKGBUILD, .SRCINFO, and install hook are all untracked, and git diff --quiet -- ... ignores untracked files. The first publish therefore exits as “No AUR package changes to publish” without committing anything, so the workflow cannot populate the package as described; check git status --porcelain or stage before deciding there are no changes.

Useful? React with 👍 / 👎.

@avifenesh avifenesh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an auto review done by revuto.

Comment thread scripts/aur/render-aur-package.sh Outdated
}

sed_escape_replacement() {
printf '%s' "$1" | sed -e 's/[\/&]/\\&/g'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an auto review done by revuto.


The renderer uses | as the sed delimiter for __SOURCE_REPO__ and __DMG_URL__ below, but sed_escape_replacement only escapes / and &. If either URL contains a literal | (allowed in a configured AUR_SOURCE_REPO/AUR_DMG_URL override), the generated sed expression is split and rendering fails. This repo has the same packaging invariant for PKGBUILD substitutions: escape the delimiter you use (or use a delimiter not present in the replacement).

# shellcheck source=/dev/null
. "$PWD/scripts/lib/package-common.sh"

stage_common_package_files "$pkgdir"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an auto review done by revuto.


stage_common_package_files copies the staged app from $APP_DIR, but the AUR package never runs ensure_app_layout before calling it. If install.sh exits without producing codex-app/start.sh (for example after an upstream layout drift that still leaves the checkout present), cp -aT "$APP_DIR" will be the first failure and makepkg reports a low-level copy error rather than the repository's explicit "Run ./install.sh first" invariant. Please call ensure_app_layout before staging, matching the local pacman builder's precondition check.

@ilysenko

ilysenko commented Jun 5, 2026

Copy link
Copy Markdown
Owner

I would not merge this yet. The overall AUR direction can be useful, but there are a couple of concrete blockers to fix first:

  1. render-aur-package.sh uses | as the sed delimiter for URL substitutions, but sed_escape_replacement does not escape |. I reproduced this locally: an override URL containing | silently renders a corrupted PKGBUILD instead of failing. Please escape the delimiter as well, ideally along with backslashes.

  2. The AUR package() path should call ensure_app_layout before stage_common_package_files, matching the native package builders. Otherwise a failed or partial install.sh run can turn into a low-level copy error instead of the repo's explicit app layout check.

I’m also cautious about the support cost here: this AUR package intentionally uses the normal networked install.sh build flow, so it may download Node runtime, Electron, npm inputs, and fallback resources during build(). That may be acceptable as a best-effort AUR package, but it should be very clear in the docs because it will likely create more AUR-specific build support requests.

@akshaynexus

Copy link
Copy Markdown
Author

Yeah makes sense will fix that shortly

@akshaynexus

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 897db3a4cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +63 to +67
"Codex.dmg::${_dmg_url}"
)
sha256sums=(
'__SOURCE_SHA256__'
'__DMG_SHA256__'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pin the DMG source before pairing it with fixed Electron

When the upstream Codex.dmg URL is replaced after this PKGBUILD is published, makepkg will fetch the new DMG because its checksum is SKIP, but the Electron archive remains fixed by _electron_version. The installer then detects the Electron version from the DMG (scripts/lib/dmg.sh:102-104) while download_electron blindly unpacks the fixed CODEX_ELECTRON_ZIP_SOURCE (scripts/lib/native-modules.sh:299-305), so an upstream Electron bump can silently produce a package with native modules built for one Electron version and a different runtime. Please either pin/verify the DMG checksum used for the rendered package or fail when the detected DMG Electron version does not match the declared AUR Electron source.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/aur.yml Outdated
-e AUR_PKGNAME="$AUR_PKGNAME" \
-e AUR_SOURCE_REPO="$AUR_SOURCE_REPO" \
-e AUR_SOURCE_REF="${{ steps.source-ref.outputs.source_ref }}" \
-e AUR_PKGVER="${{ inputs.pkgver }}" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass pkgver through env before using it in shell

When a workflow-dispatch caller supplies a pkgver containing shell metacharacters, this expression is expanded into the run: script before bash parses the docker run command, unlike source_ref which is first placed in env. A value with a quote or command substitution can therefore alter the workflow command before the renderer's validate_pkgver runs. Please route this input through an environment variable (and quote that variable) before passing it to Docker.

Useful? React with 👍 / 👎.

@akshaynexus

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eaff9a9321

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


source=(
"${_repo_dir}.tar.gz::__SOURCE_REPO__/archive/${_source_ref}.tar.gz"
"Codex.dmg::${_dmg_url}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pin the DMG source used by AUR builds

Because this AUR source entry points at the floating Codex.dmg URL while the Electron archive is pinned by _electron_version and install.sh now aborts on a detected-version mismatch, the same published AUR revision will start failing as soon as upstream replaces that DMG before a new AUR update is published. In that scenario makepkg downloads the newer DMG but still fetches the old Electron zip, so users rebuilding from a clean cache cannot install the package. Use an immutable/versioned DMG source or publish and verify a matching DMG checksum/version together with the Electron pin.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/aur.yml
set -euo pipefail
pacman -Syu --noconfirm --needed curl git
useradd -m builder
chown -R builder:builder /work

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid taking ownership of the checked-out workspace

On GitHub-hosted runners where the host runner UID differs from the Arch container's newly-created builder UID, this chown -R leaves the mounted checkout, including .git, owned by the container user after Docker exits. The later artifact/publish steps only read the rendered files, but checkout's post-job cleanup still has to update the repository metadata and can fail with permission denied, causing the manual publish workflow to fail after rendering. Create builder with the mounted workspace UID or chown the workspace back before leaving the container.

Useful? React with 👍 / 👎.

@avifenesh avifenesh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an auto review done by revuto.


Found one issue in the AUR renderer input validation that can still turn workflow/package metadata input into shell syntax when makepkg sources the rendered PKGBUILD.


validate_pkgver() {
case "$1" in
""|*[-:[:space:]]*)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an auto review done by revuto.


This validation still allows shell metacharacters even though the value is later emitted as an unquoted pkgver=__PKGVER__ assignment in the PKGBUILD and makepkg --printsrcinfo sources that file. For example, a workflow-dispatch pkgver like 1$(id>/tmp/aur-pkgver) contains no hyphen, colon, or whitespace, so it passes here; the command substitution is then executed when makepkg reads the rendered PKGBUILD. Please switch this to an allowlist for Arch pkgver characters (for example alnum plus ._+) or otherwise render the value so it cannot be evaluated as shell syntax.

@ilysenko

Copy link
Copy Markdown
Owner

Thanks again for working on this and for being willing to address the review feedback. Sorry for closing the PR without a clearer note after you had already put time into it.\n\nFor now we decided not to merge the AUR packaging workflow, mostly because we want to keep the supported package/update paths narrower until the AUR support and its maintenance expectations are clearer. This does not mean the idea is rejected permanently; we may come back to AUR support later, and your work here will be useful context if we do.\n\nI appreciate the contribution and the validation you did.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make it available on arch aur

3 participants