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
19 changes: 19 additions & 0 deletions .github/tag-api-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail

version=${1:-}
if [[ $# -ne 1 || ! "$version" =~ ^[1-9][0-9]*$ ]]; then
echo "usage: $0 PACKAGE-API-VERSION" >&2
exit 2
fi

checked_sha=$(git rev-parse HEAD)
main_ref=$(git ls-remote --exit-code origin refs/heads/main)
main_sha=${main_ref%%$'\t'*}
if [[ "$checked_sha" != "$main_sha" ]]; then
echo "Skipping api-v$version: main has advanced beyond the checked collection."
exit 0
fi

# Each version keeps its own tag when Core moves to a newer Package API.
git push origin "$checked_sha:refs/tags/api-v$version" --force
46 changes: 46 additions & 0 deletions .github/test-tag-api-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail

script_root=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
test_root=$(mktemp -d)
trap 'rm -rf -- "$test_root"' EXIT

git init --bare -q "$test_root/remote"
git init -b main -q "$test_root/collection"
cd "$test_root/collection"
git config user.name 'Package tag test'
git config user.email 'package-tag@example.invalid'
git remote add origin "$test_root/remote"
git -c commit.gpgsign=false commit -qm first --allow-empty
git push -q origin main
first=$(git rev-parse HEAD)

"$script_root/tag-api-version.sh" 1
test "$(git --git-dir="$test_root/remote" rev-parse refs/tags/api-v1)" = "$first"

git -c commit.gpgsign=false commit -qm second --allow-empty
git push -q origin main
second=$(git rev-parse HEAD)
"$script_root/tag-api-version.sh" 1
test "$(git --git-dir="$test_root/remote" rev-parse refs/tags/api-v1)" = "$second"

git -c commit.gpgsign=false commit -qm third --allow-empty
git push -q origin main
third=$(git rev-parse HEAD)
"$script_root/tag-api-version.sh" 2
test "$(git --git-dir="$test_root/remote" rev-parse refs/tags/api-v2)" = "$third"
test "$(git --git-dir="$test_root/remote" rev-parse refs/tags/api-v1)" = "$second"

# A delayed run must not replace a tag with an older collection commit.
git checkout -q --detach "$first"
"$script_root/tag-api-version.sh" 1
test "$(git --git-dir="$test_root/remote" rev-parse refs/tags/api-v1)" = "$second"

for invalid in '' 0 01 -1 '1/other'; do
if "$script_root/tag-api-version.sh" "$invalid"; then
echo "accepted invalid Package API version '$invalid'" >&2
exit 1
fi
done

echo 'Package API tag publication checks passed.'
32 changes: 32 additions & 0 deletions .github/workflows/core-tip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
./.github/test-artifact-firewall.sh
./.github/check-artifact-firewall.sh

- name: Test Package API tag publication
run: ./.github/test-tag-api-version.sh

package-api-exemptions:
runs-on: ubuntu-latest
timeout-minutes: 5
Expand All @@ -54,6 +57,8 @@ jobs:
needs: firewall
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
package-api-version: ${{ steps.package-api.outputs.version }}

steps:
- name: Check out Packages
Expand All @@ -73,6 +78,17 @@ jobs:
- name: Install Rust 1.93.0
run: rustup toolchain install 1.93.0 --profile minimal --component rustfmt --component clippy

- name: Read the checked Core revision's Package API version
id: package-api
run: |
heading=$(head -n 1 lyracore/docs/package-api.md)
version=${heading#\# Package API, version }
if [[ "$heading" == "$version" || ! "$version" =~ ^[1-9][0-9]*$ ]]; then
echo "Core does not declare a Package API version" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Check Package test formatting, lints and discovery
run: |
./collection/.github/check-core-tip.sh "$GITHUB_WORKSPACE/lyracore" \
Expand All @@ -88,6 +104,22 @@ jobs:
- name: Compile every Package against the required Core revision
run: ./collection/.github/check-core-tip.sh "$GITHUB_WORKSPACE/lyracore"

package-api-tag:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [module, datascripts, package-api-exemptions]
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- name: Check out the tested collection
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Move its Package API tag
env:
PACKAGE_API_VERSION: ${{ needs.module.outputs.package-api-version }}
run: ./.github/tag-api-version.sh "$PACKAGE_API_VERSION"

datascripts:
needs: firewall
runs-on: ubuntu-latest
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
This repository is LyraCore's Official Package Collection. Each visible top-level directory is one
independently installable Package. There is no separate registry or index file.

`main` tracks LyraCore `main`. When LyraCore starts publishing releases, this repository will use
matching tags for compatible Package revisions.
Each Package API version has a tag, such as `api-v1`. After the compatibility checks pass on
`main`, CI moves the tag for the checked Core revision's Package API version to that collection
commit. Tags for older API versions stay at their last compatible commit.

`lyracore packages add <name>` and `lyracore packages update` select the tag from the version in
the checkout's `docs/package-api.md`. A missing tag refuses the operation. Each installed Package's
Provenance Stamp records the exact collection commit it came from.

## Packages

Expand All @@ -20,15 +25,17 @@ core patch before installing it.

CI installs every Package into a clean checkout of
[`LyraCoreProject/LyraCore`](https://github.com/LyraCoreProject/LyraCore) and runs the Module library
tests against core tip. A Package API or schema incompatibility fails the collection build.
tests against the Core revision pinned in `.github/workflows/core-tip.yml`. A Package API or
schema incompatibility fails the collection build.

To run the same check locally against a clean LyraCore checkout:

```bash
./.github/check-core-tip.sh /path/to/LyraCore
```

The check refuses a core checkout whose `packages/` directory is not empty.
The check temporarily links collection Packages into Core. It restores any in-tree Packages with
matching names when it exits.

## Contributing

Expand Down
Loading