Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 116 additions & 2 deletions .github/workflows/TerminalNightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ name: 'Terminal release'
# attached to each release of the packages, whose version they carry, read from the release's
# tag as Nuget.yml reads it. Run by hand, it builds and packs without attaching anything unless
# asked to, and a pull request that touches the workflow or its scripts builds and packs the
# same way. Only the job that attaches the builds can write to the repository, and it runs no
# code from it.
# same way. Only the jobs that attach the builds and publish the packages can write, and they run
# no code from the repository.
# https://github.com/asc-community/AngouriMath/issues/539
# The AUR's amcli-bin and the Nix flake's release.json are rendered from the same archives, and
# published with the release. https://github.com/asc-community/AngouriMath/issues/1660
on:
release:
types: [published]
Expand All @@ -17,6 +19,7 @@ on:
- 'Sources/Terminal/AngouriMath.Terminal/pack-deb-linux.sh'
- 'Sources/Terminal/AngouriMath.Terminal/amcli.1'
- 'Sources/Terminal/AngouriMath.Terminal/amcli.bash'
- 'Sources/Terminal/AngouriMath.Terminal/packaging/**'
workflow_dispatch:
inputs:
version:
Expand All @@ -34,6 +37,7 @@ jobs:
permissions:
contents: read
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}

steps:
Expand Down Expand Up @@ -129,3 +133,113 @@ jobs:
'angourimath-terminal-arm64.deb' \
-R "$GITHUB_REPOSITORY" \
--clobber

# The PKGBUILD for the AUR's amcli-bin, its .SRCINFO, and the release.json the Nix flake reads,
# from the archives the build made. Rendered on every run, so that a pull request that touches
# them shows they still render, and published only with a release.
TerminalPackagesRender:
needs: TerminalBuild
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- uses: actions/download-artifact@v4
with:
name: angourimath-terminal
path: archives

# The tag's own files where there is a tag; for a pull request or a run by hand, the commit
# being built.
- name: 'Render'
env:
VERSION: ${{ needs.TerminalBuild.outputs.version }}
TAG: ${{ needs.TerminalBuild.outputs.tag }}
run: |
sum() { sha256sum "archives/angourimath-terminal-$1.zip" | cut -d' ' -f1; }
if git rev-parse -q --verify "refs/tags/$TAG" > /dev/null; then ref="$TAG"; else ref=HEAD; fi
mkdir -p packages
PACKAGING_REF="$ref" Sources/Terminal/AngouriMath.Terminal/packaging/render-pkgbuild.sh \
"$VERSION" "$(sum linux-x64)" "$(sum linux-arm64)" "$(sum linux-arm)" > packages/PKGBUILD
printf '{\n "version": "%s",\n "sha256": {\n "linux-x64": "%s",\n "linux-arm64": "%s",\n "linux-arm": "%s"\n }\n}\n' \
"$VERSION" "$(sum linux-x64)" "$(sum linux-arm64)" "$(sum linux-arm)" > packages/release.json
cat packages/PKGBUILD packages/release.json

# makepkg will not run as root, and an Arch container is the only place it is.
- name: '.SRCINFO'
run: |
docker run --rm -v "$PWD/packages:/packages" archlinux:base-devel bash -c \
'useradd -m builder && cp /packages/PKGBUILD /home/builder/ && cd /home/builder && su builder -c "makepkg --printsrcinfo" > /packages/.SRCINFO'
cat packages/.SRCINFO

- name: 'Keep the packages'
uses: actions/upload-artifact@v4
with:
name: amcli-packages
retention-days: 7
include-hidden-files: true
path: packages

# The PKGBUILD is pushed to the AUR where the repository has the AUR_SSH_KEY secret, the private
# key of the AUR account that owns amcli-bin; without it nothing is pushed. release.json goes to
# master by a pull request, which is what moves the flake to the release.
TerminalPackagesPublish:
needs: [TerminalBuild, TerminalRelease, TerminalPackagesRender]
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.release)
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.repository.default_branch }}

- uses: actions/download-artifact@v4
with:
name: amcli-packages
path: packages

- name: 'The flake follows the release'
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ needs.TerminalBuild.outputs.version }}
run: |
branch="amcli-release-$VERSION"
cp packages/release.json Sources/Terminal/AngouriMath.Terminal/packaging/release.json
if git diff --quiet; then echo "release.json already names $VERSION"; exit 0; fi
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git switch -c "$branch"
git commit -am "The Nix flake installs amcli $VERSION"
git push --force origin "$branch"
gh pr create --base "${{ github.event.repository.default_branch }}" --head "$branch" \
--title "The Nix flake installs amcli $VERSION" \
--body "release.json for the $VERSION archives, rendered by the Terminal release workflow (#1660)."

- name: 'The AUR follows the release'
env:
AUR_SSH_KEY: ${{ secrets.AUR_SSH_KEY }}
VERSION: ${{ needs.TerminalBuild.outputs.version }}
run: |
if [ -z "$AUR_SSH_KEY" ]; then echo 'No AUR_SSH_KEY secret: amcli-bin is not pushed.'; exit 0; fi
install -d -m 700 ~/.ssh
printf '%s\n' "$AUR_SSH_KEY" > ~/.ssh/aur && chmod 600 ~/.ssh/aur
# The host key the AUR publishes on https://aur.archlinux.org, and no other.
ssh-keyscan -t ed25519 aur.archlinux.org > aur.key 2> /dev/null
[ "$(ssh-keygen -lf aur.key | cut -d' ' -f2)" = 'SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4' ] \
|| { echo 'aur.archlinux.org did not present its published Ed25519 key'; exit 1; }
cat aur.key >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND='ssh -i ~/.ssh/aur -o IdentitiesOnly=yes'
git clone ssh://aur@aur.archlinux.org/amcli-bin.git aur
cp packages/PKGBUILD packages/.SRCINFO aur/
cd aur
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add PKGBUILD .SRCINFO
git diff --cached --quiet || { git commit -m "amcli $VERSION"; git push origin HEAD:master; }
8 changes: 8 additions & 0 deletions Sources/Terminal/AngouriMath.Terminal/packaging/release.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"version": "2.6.0",
"sha256": {
"linux-x64": "61998c4f322f1f8adfed8fa4324dd382c822ca6c30c2c49165bcbae95d36f9da",
"linux-arm64": "b8e5ffe84d011c41f1c89002855c40f593d0f7f0cd7ba945fbf7ff215aea1a26",
"linux-arm": "d4fcf4bb69df3f5f531046ca4fddaf9285f2b22a0efe412d8a498747a456087b"
}
}
58 changes: 58 additions & 0 deletions Sources/Terminal/AngouriMath.Terminal/packaging/render-pkgbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
# Writes the AUR's amcli-bin PKGBUILD for a release to standard output, from the release's version
# and the SHA-256 of its three Linux archives. The man page, the completion script and the licence
# are fetched from the tag, so they are hashed as the tag has them: PACKAGING_REF names it, v2.6.0
# for 2.6.0, and is the release's tag where the workflow runs this.
# https://github.com/asc-community/AngouriMath/issues/1660
set -euo pipefail
version="${1:?usage: render-pkgbuild.sh VERSION SHA256_LINUX_X64 SHA256_LINUX_ARM64 SHA256_LINUX_ARM}"
x64="${2:?}"; arm64="${3:?}"; arm="${4:?}"
ref="${PACKAGING_REF:-v$version}"
sum() { git show "$ref:$1" | sha256sum | cut -d' ' -f1; }
# A pkgver has no hyphen: 2.7.0-beta.1 is packed as 2.7.0_beta.1, from the tag v2.7.0-beta.1.
cat <<PKGBUILD
# Generated by Sources/Terminal/AngouriMath.Terminal/packaging/render-pkgbuild.sh in
# https://github.com/asc-community/AngouriMath for each release.
pkgname=amcli-bin
pkgver=${version//-/_}
pkgrel=1
pkgdesc="AngouriMath's terminal and command-line computer algebra system"
arch=('x86_64' 'aarch64' 'armv7h')
url="https://am.angouri.org"
license=('MIT')
depends=('icu' 'zlib' 'openssl' 'krb5' 'gcc-libs')
provides=('amcli')
conflicts=('amcli')
options=('!strip' '!debug')
_tag="v${version}"
_release="https://github.com/asc-community/AngouriMath/releases/download/\${_tag}"
_raw="https://raw.githubusercontent.com/asc-community/AngouriMath/\${_tag}"
source=("amcli-\${_tag}.1::\${_raw}/Sources/Terminal/AngouriMath.Terminal/amcli.1"
"amcli-\${_tag}.bash::\${_raw}/Sources/Terminal/AngouriMath.Terminal/amcli.bash"
"LICENSE-\${_tag}.md::\${_raw}/LICENSE.md")
source_x86_64=("angourimath-terminal-linux-x64-\${_tag}.zip::\${_release}/angourimath-terminal-linux-x64.zip")
source_aarch64=("angourimath-terminal-linux-arm64-\${_tag}.zip::\${_release}/angourimath-terminal-linux-arm64.zip")
source_armv7h=("angourimath-terminal-linux-arm-\${_tag}.zip::\${_release}/angourimath-terminal-linux-arm.zip")
sha256sums=('$(sum Sources/Terminal/AngouriMath.Terminal/amcli.1)'
'$(sum Sources/Terminal/AngouriMath.Terminal/amcli.bash)'
'$(sum LICENSE.md)')
sha256sums_x86_64=('${x64}')
sha256sums_aarch64=('${arm64}')
sha256sums_armv7h=('${arm}')

package() {
case "\$CARCH" in
x86_64) _runtime=linux-x64 ;;
aarch64) _runtime=linux-arm64 ;;
armv7h) _runtime=linux-arm ;;
esac
install -d "\$pkgdir/opt/amcli" "\$pkgdir/usr/bin"
cp -r "\$srcdir/\$_runtime/." "\$pkgdir/opt/amcli/"
# The runtime's tracing provider wants LTTng, which nothing here uses.
rm -f "\$pkgdir/opt/amcli/libcoreclrtraceptprovider.so"
ln -s /opt/amcli/AngouriMath.Terminal "\$pkgdir/usr/bin/amcli"
install -Dm644 "amcli-\${_tag}.1" "\$pkgdir/usr/share/man/man1/amcli.1"
install -Dm644 "amcli-\${_tag}.bash" "\$pkgdir/usr/share/bash-completion/completions/amcli"
install -Dm644 "LICENSE-\${_tag}.md" "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE.md"
}
PKGBUILD
8 changes: 8 additions & 0 deletions Sources/Terminal/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ To uninstall it, run
dotnet tool uninstall --global AngouriMath.Terminal
```

### With Nix

The repository is a flake that installs the latest release's build, on x86-64, ARM64 and ARMv7 Linux:
```
nix run github:asc-community/AngouriMath -- simp "x + x"
nix profile install github:asc-community/AngouriMath
```

## One command, from a script

With a command after it, `amcli` answers once and exits, without opening the terminal or starting
Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# amcli, the AngouriMath terminal, as the release built it: `nix run github:asc-community/AngouriMath`.
# The version and the archives' hashes are in Sources/Terminal/AngouriMath.Terminal/packaging/release.json,
# which the Terminal release workflow updates after each release.
# https://github.com/asc-community/AngouriMath/issues/1660
{
description = "amcli, the AngouriMath terminal and command-line calculator";

inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";

outputs = { self, nixpkgs }:
let
release = builtins.fromJSON (builtins.readFile ./Sources/Terminal/AngouriMath.Terminal/packaging/release.json);
runtimes = { x86_64-linux = "linux-x64"; aarch64-linux = "linux-arm64"; armv7l-linux = "linux-arm"; };
forEachSystem = f: nixpkgs.lib.genAttrs (builtins.attrNames runtimes)
(system: f nixpkgs.legacyPackages.${system} runtimes.${system});
in
{
packages = forEachSystem (pkgs: runtime: rec {
amcli = pkgs.stdenv.mkDerivation {
pname = "amcli";
inherit (release) version;
src = pkgs.fetchurl {
url = "https://github.com/asc-community/AngouriMath/releases/download/v${release.version}/angourimath-terminal-${runtime}.zip";
sha256 = release.sha256.${runtime};
};
sourceRoot = runtime;
nativeBuildInputs = [ pkgs.unzip pkgs.autoPatchelfHook pkgs.makeWrapper pkgs.installShellFiles ];
buildInputs = [ pkgs.stdenv.cc.cc.lib pkgs.zlib pkgs.icu pkgs.openssl pkgs.krb5 ];
# The runtime's tracing provider wants LTTng, which nothing here uses.
postPatch = "rm -f libcoreclrtraceptprovider.so";
dontBuild = true;
# The assemblies are executable in the archive, and strip rewrites a PE file it is given:
# a stripped System.Private.CoreLib.dll is a bad image to the runtime.
dontStrip = true;
installPhase = ''
runHook preInstall
mkdir -p $out/lib/amcli
cp -r . $out/lib/amcli
# .NET opens ICU and OpenSSL by name at run time, which autoPatchelf does not see.
makeWrapper $out/lib/amcli/AngouriMath.Terminal $out/bin/amcli \
--prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath [ pkgs.icu pkgs.openssl pkgs.zlib pkgs.krb5 ]}
installManPage ${./Sources/Terminal/AngouriMath.Terminal/amcli.1}
installShellCompletion --bash --name amcli ${./Sources/Terminal/AngouriMath.Terminal/amcli.bash}
runHook postInstall
'';
meta = {
description = "AngouriMath's terminal and command-line computer algebra system";
homepage = "https://am.angouri.org";
license = pkgs.lib.licenses.mit;
sourceProvenance = [ pkgs.lib.sourceTypes.binaryNativeCode pkgs.lib.sourceTypes.binaryBytecode ];
platforms = builtins.attrNames runtimes;
mainProgram = "amcli";
};
};
default = amcli;
});
};
}
Loading