From cd9775014cdcbc25ea301d69b6db9c3064c1e690 Mon Sep 17 00:00:00 2001 From: zz_y Date: Tue, 22 Sep 2026 20:32:44 +0000 Subject: [PATCH 1/4] ci: automatically track verified ASAPPlanner main revisions --- .github/workflows/mvp-ci.yml | 12 ++++-- .github/workflows/planner-main-merge.yml | 42 +++++++++++++++++++++ .github/workflows/planner-main-sync.yml | 47 ++++++++++++++++++++++++ Cargo.lock | 37 +++++++------------ Cargo.toml | 8 ++-- scripts/ci/README.md | 27 ++++++++++++++ scripts/ci/test_update_planner.py | 41 +++++++++++++++++++++ scripts/ci/update_planner.py | 39 ++++++++++++++++++++ 8 files changed, 222 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/planner-main-merge.yml create mode 100644 .github/workflows/planner-main-sync.yml create mode 100644 scripts/ci/README.md create mode 100644 scripts/ci/test_update_planner.py create mode 100644 scripts/ci/update_planner.py diff --git a/.github/workflows/mvp-ci.yml b/.github/workflows/mvp-ci.yml index 03ec24b2..eede4217 100644 --- a/.github/workflows/mvp-ci.yml +++ b/.github/workflows/mvp-ci.yml @@ -49,6 +49,10 @@ jobs: # post-step can package `target`; registry/git inputs are sufficient. cache-targets: false + - name: Test Planner dependency updater + working-directory: ASAPQuery-backend + run: python3 -m unittest discover -s scripts/ci -p 'test_*.py' + - name: Check workspace formatting working-directory: ASAPQuery-backend # `--all` also follows this workspace's sibling path dependencies. @@ -59,20 +63,20 @@ jobs: env: CARGO_NET_GIT_FETCH_WITH_CLI: "true" working-directory: ASAPQuery-backend - run: cargo check --workspace + run: cargo check --workspace --locked - name: Lint workspace env: CARGO_NET_GIT_FETCH_WITH_CLI: "true" working-directory: ASAPQuery-backend # Preserve the existing warning policy while expanding runtime coverage. - run: cargo clippy --workspace --all-targets -- -D warnings + run: cargo clippy --workspace --all-targets --locked -- -D warnings - name: Build process-test control plane env: CARGO_NET_GIT_FETCH_WITH_CLI: "true" working-directory: ASAPQuery-backend - run: cargo build -p control_plane --bin control_plane + run: cargo build -p control_plane --bin control_plane --locked - name: Test workspace env: @@ -84,4 +88,4 @@ jobs: # Match scripts/e2e.sh to avoid competing flushers exhausting those waits. run: | export ASAP_E2E_CONTROL_PLANE_BIN="$PWD/target/debug/control_plane" - cargo test --workspace -- --test-threads=1 + cargo test --workspace --locked -- --test-threads=1 diff --git a/.github/workflows/planner-main-merge.yml b/.github/workflows/planner-main-merge.yml new file mode 100644 index 00000000..587c0d2f --- /dev/null +++ b/.github/workflows/planner-main-merge.yml @@ -0,0 +1,42 @@ +name: Merge verified Planner update + +on: + workflow_run: + workflows: ['MVP CI'] + types: [completed] + +permissions: + contents: write + pull-requests: write + +concurrency: + group: planner-main-merge + cancel-in-progress: false + +jobs: + merge: + if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' + runs-on: ubuntu-latest + steps: + # Never check out or execute PR content in this privileged workflow. + - uses: actions/github-script@v7 + with: + script: | + const {owner, repo} = context.repo; + const run = context.payload.workflow_run; + const prs = await github.rest.pulls.list({owner, repo, state: 'open', base: 'main', head: `${owner}:automation/planner-main`}); + if (prs.data.length !== 1) return; + const {data: pr} = await github.rest.pulls.get({owner, repo, pull_number: prs.data[0].number}); + if (pr.head.repo.full_name !== `${owner}/${repo}` || pr.head.sha !== run.head_sha || pr.draft) return; + const testedPr = run.pull_requests.find(p => p.number === pr.number); + if (!testedPr || testedPr.base.sha !== pr.base.sha) { + core.info('Main changed since this CI run; wait for the next updater refresh.'); + return; + } + const files = await github.paginate(github.rest.pulls.listFiles, {owner, repo, pull_number: pr.number}); + if (!files.length || files.some(f => !['Cargo.toml', 'Cargo.lock'].includes(f.filename))) { + core.setFailed('Planner automation may only change Cargo.toml and Cargo.lock'); + return; + } + // Required branch protection checks still apply; sha prevents merging a newer, untested head. + await github.rest.pulls.merge({owner, repo, pull_number: pr.number, sha: run.head_sha, merge_method: 'squash'}); diff --git a/.github/workflows/planner-main-sync.yml b/.github/workflows/planner-main-sync.yml new file mode 100644 index 00000000..35f21ba9 --- /dev/null +++ b/.github/workflows/planner-main-sync.yml @@ -0,0 +1,47 @@ +name: Sync Planner main + +on: + schedule: + - cron: '17 * * * *' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: planner-main-sync + cancel-in-progress: false + +jobs: + update: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + with: + ref: main + - name: Configure private Cargo dependencies + env: + ASAP_CI_REPO_TOKEN: ${{ secrets.ASAP_CI_REPO_TOKEN }} + run: git config --global url."https://x-access-token:${ASAP_CI_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + - name: Resolve Planner main + env: + CARGO_NET_GIT_FETCH_WITH_CLI: 'true' + run: python3 scripts/ci/update_planner.py + # A repository token is needed so the resulting PR triggers MVP CI. + # GITHUB_TOKEN-created PRs do not trigger pull_request workflows. + - uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.ASAP_CI_REPO_TOKEN }} + branch: automation/planner-main + base: main + add-paths: | + Cargo.toml + Cargo.lock + commit-message: 'build: sync ASAPPlanner main' + title: 'build: sync ASAPPlanner main' + body: | + Before this PR: the backend pins an earlier ASAPPlanner revision. + After this PR: all four Planner dependencies and Cargo.lock use the latest main revision observed by the updater. + + MVP CI runs workspace formatting, checking, linting, and all workspace tests, including process E2E. Successful updates are merged automatically; incompatible updates remain open for investigation. diff --git a/Cargo.lock b/Cargo.lock index a49ca3f3..aa415f34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,7 +364,7 @@ dependencies = [ [[package]] name = "asap-aware-mapping" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" dependencies = [ "asap-types", "asap_sketchlib 0.3.0 (git+https://github.com/ProjectASAP/asap_sketchlib)", @@ -376,7 +376,7 @@ dependencies = [ [[package]] name = "asap-frontend-promql" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" dependencies = [ "asap-types", "promql-parser 0.10.0 (git+https://github.com/ProjectASAP/promql-parser?rev=9fede7eecca923c9882fe256484d00d37f8706cb)", @@ -385,7 +385,7 @@ dependencies = [ [[package]] name = "asap-frontend-sql" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" dependencies = [ "asap-sql-function-catalog", "asap-types", @@ -408,12 +408,12 @@ dependencies = [ [[package]] name = "asap-sql-function-catalog" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" [[package]] name = "asap-types" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" dependencies = [ "serde", "serde_json", @@ -1660,7 +1660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2277,7 +2277,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2304,15 +2304,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.18" @@ -3084,7 +3075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools 0.14.0", + "itertools 0.10.5", "log", "multimap", "once_cell", @@ -3104,7 +3095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.10.5", "proc-macro2", "quote", "syn 2.0.119", @@ -3242,7 +3233,7 @@ dependencies = [ "once_cell", "socket2 0.5.10", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3518,7 +3509,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3963,7 +3954,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4475,7 +4466,7 @@ version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" dependencies = [ - "rand 0.9.5", + "rand 0.10.2", ] [[package]] @@ -4738,7 +4729,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f1da29da..f59369ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,10 @@ asap_sketchlib = { git = "https://github.com/ProjectASAP/asap_sketchlib", branch [workspace.dependencies] # Keep Planner frontends, selection, and IR on the same immutable revision. # Alias upstream asap-types because this workspace also defines asap_types. -planner-types = { package = "asap-types", git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } -asap-aware-mapping = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } -asap-frontend-promql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } -asap-frontend-sql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } +planner-types = { package = "asap-types", git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } +asap-aware-mapping = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } +asap-frontend-promql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } +asap-frontend-sql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } # Shared external deps (used by 2+ crates) serde = { version = "1.0", features = ["derive"] } diff --git a/scripts/ci/README.md b/scripts/ci/README.md new file mode 100644 index 00000000..1fcec318 --- /dev/null +++ b/scripts/ci/README.md @@ -0,0 +1,27 @@ +# Planner main updates + +The backend keeps reproducible Planner revisions in `Cargo.toml` and `Cargo.lock`. +`Sync Planner main` checks upstream main hourly (or on manual dispatch), updates +all four Planner dependencies together, and opens or refreshes +`automation/planner-main` against backend main. GitHub scheduled runs can be delayed. + +The existing `ASAP_CI_REPO_TOKEN` secret must have read access to private dependency +repositories and **Contents and Pull requests write** access to this backend repo. +The updater uses this token to create its PR so GitHub triggers `MVP CI`. +The merge workflow uses the repository's `GITHUB_TOKEN` and does not require +GitHub's optional auto-merge feature to be enabled. + +MVP CI uses `--locked` and runs the workspace checks, Clippy, unit tests, and +process E2E tests. Only a successful run for the current update PR head can +trigger the merge workflow; it also verifies the repository, branch, base, and +that main has not advanced since that run and only the two Cargo files changed. Branch protection remains in force. +Failed updates stay open and main retains its last verified version. Fix an +upstream incompatibility separately, or let the next upstream update refresh the +PR. An automation failure is visible in Actions; check token permissions there. + +Locally, run `python3 scripts/ci/update_planner.py` from the repository root, +then run the same checks as MVP CI. Updater unit tests run with: + +```sh +python3 -m unittest discover -s scripts/ci -p 'test_*.py' +``` diff --git a/scripts/ci/test_update_planner.py b/scripts/ci/test_update_planner.py new file mode 100644 index 00000000..783e8945 --- /dev/null +++ b/scripts/ci/test_update_planner.py @@ -0,0 +1,41 @@ +"""Guard atomic Planner revision updates and reject unexpected manifests.""" +import unittest + +from update_planner import pin_planner + + +class PlannerPinTests(unittest.TestCase): + revision = "a" * 40 + manifest = ''.join( + f'{name} = {{ git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "{"b" * 40}" }}\n' + for name in ['planner-types', 'asap-aware-mapping', 'asap-frontend-promql', 'asap-frontend-sql'] + ) + + def test_atomic_and_idempotent(self): + """All four dependencies advance together, without touching other Git pins.""" + other = 'other = { git = "https://example.com/other", branch = "main" }\n' + result = pin_planner(self.manifest + other, self.revision) + self.assertEqual(result.count(f'rev = "{self.revision}"'), 4) + self.assertTrue(result.endswith(other)) + self.assertEqual(pin_planner(result, self.revision), result) + + def test_accepts_branch_selector(self): + """A branch-based Planner manifest can be converted to reproducible pins.""" + result = pin_planner(self.manifest.replace(f'rev = "{"b" * 40}"', 'branch = "main"'), self.revision) + self.assertEqual(result.count(f'rev = "{self.revision}"'), 4) + + def test_rejects_changed_dependency_layout(self): + """A removed dependency or missing selector requires a deliberate updater change.""" + for manifest in [self.manifest.split('\n', 1)[1], self.manifest.replace(f', rev = "{"b" * 40}"', '')]: + with self.subTest(manifest=manifest), self.assertRaises(ValueError): + pin_planner(manifest, self.revision) + + def test_rejects_invalid_revision(self): + """Branch names and truncated SHAs cannot become immutable pins.""" + for revision in ['main', 'abc123', 'z' * 40]: + with self.subTest(revision=revision), self.assertRaises(ValueError): + pin_planner(self.manifest, revision) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/ci/update_planner.py b/scripts/ci/update_planner.py new file mode 100644 index 00000000..348a80a9 --- /dev/null +++ b/scripts/ci/update_planner.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Pin every Planner workspace dependency to one main revision, then resolve it.""" +import re +import subprocess +from pathlib import Path + +URL = "https://github.com/ProjectASAP/ASAPPlanner" + + +def pin_planner(manifest: str, revision: str) -> str: + if not re.fullmatch(r"[0-9a-f]{40}", revision): + raise ValueError("Expected a full Planner commit SHA") + count = 0 + lines = [] + for line in manifest.splitlines(keepends=True): + if re.search(r'git\s*=\s*"' + re.escape(URL) + r'"', line): + line, replaced = re.subn(r'(?:rev|branch|tag)\s*=\s*"[^"]+"', f'rev = "{revision}"', line) + if replaced != 1: + raise ValueError("Planner dependency must have exactly one Git revision selector") + count += 1 + lines.append(line) + if count != 4: + raise ValueError(f"Expected four Planner dependencies, found {count}; review the updater") + return "".join(lines) + + +if __name__ == "__main__": + revision = subprocess.check_output( + ["git", "ls-remote", URL, "refs/heads/main"], text=True + ).split()[0] + path = Path("Cargo.toml") + original = path.read_text() + updated = pin_planner(original, revision) + if updated == original: + print(f"Planner already pinned to main: {revision}") + raise SystemExit(0) + path.write_text(updated) + subprocess.run(["cargo", "update", "-p", "asap-aware-mapping"], check=True) + print(f"Planner main: {revision}") From c57f91b1fdbea88c49fff5c09345ed8d12b92b71 Mon Sep 17 00:00:00 2001 From: zz_y Date: Tue, 22 Sep 2026 20:35:19 +0000 Subject: [PATCH 2/4] ci: reuse Planner synchronization script and workflow from PR 765 --- .github/workflows/planner-main-merge.yml | 2 +- .github/workflows/planner-main-sync.yml | 47 --------------- .github/workflows/sync-asapplanner-main.yml | 45 ++++++++++++++ Cargo.lock | 29 +++------ scripts/ci/README.md | 9 ++- scripts/ci/test_sync_planner.py | 67 +++++++++++++++++++++ scripts/ci/test_update_planner.py | 41 ------------- scripts/ci/update_planner.py | 39 ------------ scripts/sync-asapplanner-main.sh | 35 +++++++++++ 9 files changed, 164 insertions(+), 150 deletions(-) delete mode 100644 .github/workflows/planner-main-sync.yml create mode 100644 .github/workflows/sync-asapplanner-main.yml create mode 100644 scripts/ci/test_sync_planner.py delete mode 100644 scripts/ci/test_update_planner.py delete mode 100644 scripts/ci/update_planner.py create mode 100755 scripts/sync-asapplanner-main.sh diff --git a/.github/workflows/planner-main-merge.yml b/.github/workflows/planner-main-merge.yml index 587c0d2f..45c882ff 100644 --- a/.github/workflows/planner-main-merge.yml +++ b/.github/workflows/planner-main-merge.yml @@ -24,7 +24,7 @@ jobs: script: | const {owner, repo} = context.repo; const run = context.payload.workflow_run; - const prs = await github.rest.pulls.list({owner, repo, state: 'open', base: 'main', head: `${owner}:automation/planner-main`}); + const prs = await github.rest.pulls.list({owner, repo, state: 'open', base: 'main', head: `${owner}:automation/sync-asapplanner-main`}); if (prs.data.length !== 1) return; const {data: pr} = await github.rest.pulls.get({owner, repo, pull_number: prs.data[0].number}); if (pr.head.repo.full_name !== `${owner}/${repo}` || pr.head.sha !== run.head_sha || pr.draft) return; diff --git a/.github/workflows/planner-main-sync.yml b/.github/workflows/planner-main-sync.yml deleted file mode 100644 index 35f21ba9..00000000 --- a/.github/workflows/planner-main-sync.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Sync Planner main - -on: - schedule: - - cron: '17 * * * *' - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: planner-main-sync - cancel-in-progress: false - -jobs: - update: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@v4 - with: - ref: main - - name: Configure private Cargo dependencies - env: - ASAP_CI_REPO_TOKEN: ${{ secrets.ASAP_CI_REPO_TOKEN }} - run: git config --global url."https://x-access-token:${ASAP_CI_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" - - name: Resolve Planner main - env: - CARGO_NET_GIT_FETCH_WITH_CLI: 'true' - run: python3 scripts/ci/update_planner.py - # A repository token is needed so the resulting PR triggers MVP CI. - # GITHUB_TOKEN-created PRs do not trigger pull_request workflows. - - uses: peter-evans/create-pull-request@v7 - with: - token: ${{ secrets.ASAP_CI_REPO_TOKEN }} - branch: automation/planner-main - base: main - add-paths: | - Cargo.toml - Cargo.lock - commit-message: 'build: sync ASAPPlanner main' - title: 'build: sync ASAPPlanner main' - body: | - Before this PR: the backend pins an earlier ASAPPlanner revision. - After this PR: all four Planner dependencies and Cargo.lock use the latest main revision observed by the updater. - - MVP CI runs workspace formatting, checking, linting, and all workspace tests, including process E2E. Successful updates are merged automatically; incompatible updates remain open for investigation. diff --git a/.github/workflows/sync-asapplanner-main.yml b/.github/workflows/sync-asapplanner-main.yml new file mode 100644 index 00000000..29ffd235 --- /dev/null +++ b/.github/workflows/sync-asapplanner-main.yml @@ -0,0 +1,45 @@ +name: Sync ASAPPlanner main + +on: + schedule: + - cron: "17 6 * * *" + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +concurrency: + group: sync-asapplanner-main + cancel-in-progress: true + +jobs: + update: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout backend + uses: actions/checkout@v4 + + - name: Configure private Cargo dependencies + env: + ASAP_CI_REPO_TOKEN: ${{ secrets.ASAP_CI_REPO_TOKEN }} + run: git config --global url."https://x-access-token:${ASAP_CI_REPO_TOKEN}@github.com/".insteadOf "https://github.com/" + + - name: Update Planner revision and lockfile + env: + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + run: ./scripts/sync-asapplanner-main.sh + + - name: Create or update synchronization PR + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.ASAP_CI_REPO_TOKEN }} + branch: automation/sync-asapplanner-main + delete-branch: true + commit-message: "chore: sync ASAPPlanner main" + title: "chore: sync ASAPPlanner main" + body: | + Updates all ASAPPlanner workspace dependencies to the current `main` commit and regenerates `Cargo.lock`. + + MVP CI validates formatting, compilation, linting and tests. A semantic Planner change stays visible as a failing synchronization PR until the backend adaptation is added. diff --git a/Cargo.lock b/Cargo.lock index aa415f34..1ecdfaa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1660,7 +1660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2277,7 +2277,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2615,7 +2615,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3075,7 +3075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools 0.10.5", + "itertools 0.13.0", "log", "multimap", "once_cell", @@ -3095,7 +3095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.13.0", "proc-macro2", "quote", "syn 2.0.119", @@ -3233,7 +3233,7 @@ dependencies = [ "once_cell", "socket2 0.5.10", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3496,7 +3496,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3509,7 +3509,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3954,7 +3954,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4729,7 +4729,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4806,15 +4806,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.61.2" diff --git a/scripts/ci/README.md b/scripts/ci/README.md index 1fcec318..10c083eb 100644 --- a/scripts/ci/README.md +++ b/scripts/ci/README.md @@ -1,9 +1,9 @@ # Planner main updates The backend keeps reproducible Planner revisions in `Cargo.toml` and `Cargo.lock`. -`Sync Planner main` checks upstream main hourly (or on manual dispatch), updates +`Sync ASAPPlanner main` checks upstream main daily (or on manual dispatch), updates all four Planner dependencies together, and opens or refreshes -`automation/planner-main` against backend main. GitHub scheduled runs can be delayed. +`automation/sync-asapplanner-main` against backend main. GitHub scheduled runs can be delayed. The existing `ASAP_CI_REPO_TOKEN` secret must have read access to private dependency repositories and **Contents and Pull requests write** access to this backend repo. @@ -19,9 +19,12 @@ Failed updates stay open and main retains its last verified version. Fix an upstream incompatibility separately, or let the next upstream update refresh the PR. An automation failure is visible in Actions; check token permissions there. -Locally, run `python3 scripts/ci/update_planner.py` from the repository root, +Locally, run `./scripts/sync-asapplanner-main.sh` from the repository root, then run the same checks as MVP CI. Updater unit tests run with: ```sh python3 -m unittest discover -s scripts/ci -p 'test_*.py' ``` + +The sync script and scheduled workflow are shared with PR #765, at the same paths +and with the same automation branch; there is only one updater. diff --git a/scripts/ci/test_sync_planner.py b/scripts/ci/test_sync_planner.py new file mode 100644 index 00000000..cf06f427 --- /dev/null +++ b/scripts/ci/test_sync_planner.py @@ -0,0 +1,67 @@ +"""Exercise the shared sync script without accessing GitHub or Cargo registries.""" +import os +from pathlib import Path +import subprocess +import tempfile +import unittest + +SCRIPT = Path(__file__).resolve().parents[1] / "sync-asapplanner-main.sh" + + +class PlannerSyncTests(unittest.TestCase): + revision = "a" * 40 + manifest = ''.join( + f'{name} = {{ git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "{"b" * 40}" }}\n' + for name in ['planner-types', 'asap-aware-mapping', 'asap-frontend-promql', 'asap-frontend-sql'] + ) + + def run_sync(self, manifest, revision=None, cargo_status=0): + temp = tempfile.TemporaryDirectory() + self.addCleanup(temp.cleanup) + root = Path(temp.name) + (root / 'Cargo.toml').write_text(manifest) + (root / 'git').write_text('#!/bin/sh\nprintf "%s refs/heads/main\\n" "$TEST_REV"\n') + (root / 'cargo').write_text('#!/bin/sh\nprintf "%s\\n" "$@" > cargo-args\nexit "$TEST_CARGO_STATUS"\n') + for name in ['git', 'cargo']: + (root / name).chmod(0o755) + env = dict(os.environ, PATH=f'{root}:{os.environ["PATH"]}', + TEST_REV=self.revision if revision is None else revision, + TEST_CARGO_STATUS=str(cargo_status)) + result = subprocess.run(['bash', str(SCRIPT)], cwd=root, env=env, capture_output=True, text=True) + return root, result + + def test_updates_all_dependencies_and_lock_resolution(self): + """All Planner pins and Cargo's requested revision agree, preserving unrelated pins.""" + other = 'other = { git = "https://example.com/other", rev = "unchanged" }\n' + root, result = self.run_sync(self.manifest + other) + self.assertEqual(result.returncode, 0, result.stderr) + updated = (root / 'Cargo.toml').read_text() + self.assertEqual(updated.count(f'rev = "{self.revision}"'), 4) + self.assertTrue(updated.endswith(other)) + self.assertEqual((root / 'cargo-args').read_text().splitlines(), [ + 'update', '-p', 'asap-types@0.1.0', '-p', 'asap-aware-mapping', + '-p', 'asap-frontend-promql', '-p', 'asap-frontend-sql', '--precise', self.revision]) + + def test_invalid_revision_does_not_mutate_manifest(self): + """An upstream lookup failure cannot produce a malformed pin.""" + root, result = self.run_sync(self.manifest, revision='') + self.assertNotEqual(result.returncode, 0) + self.assertEqual((root / 'Cargo.toml').read_text(), self.manifest) + self.assertFalse((root / 'cargo-args').exists()) + + def test_unexpected_layout_does_not_partially_update(self): + """Removing a dependency requires deliberate updater changes.""" + manifest = self.manifest.split('\n', 1)[1] + root, result = self.run_sync(manifest) + self.assertNotEqual(result.returncode, 0) + self.assertEqual((root / 'Cargo.toml').read_text(), manifest) + self.assertFalse((root / 'cargo-args').exists()) + + def test_cargo_failure_is_reported(self): + """Lock resolution failure stops the workflow before PR publication.""" + _, result = self.run_sync(self.manifest, cargo_status=1) + self.assertNotEqual(result.returncode, 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/ci/test_update_planner.py b/scripts/ci/test_update_planner.py deleted file mode 100644 index 783e8945..00000000 --- a/scripts/ci/test_update_planner.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Guard atomic Planner revision updates and reject unexpected manifests.""" -import unittest - -from update_planner import pin_planner - - -class PlannerPinTests(unittest.TestCase): - revision = "a" * 40 - manifest = ''.join( - f'{name} = {{ git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "{"b" * 40}" }}\n' - for name in ['planner-types', 'asap-aware-mapping', 'asap-frontend-promql', 'asap-frontend-sql'] - ) - - def test_atomic_and_idempotent(self): - """All four dependencies advance together, without touching other Git pins.""" - other = 'other = { git = "https://example.com/other", branch = "main" }\n' - result = pin_planner(self.manifest + other, self.revision) - self.assertEqual(result.count(f'rev = "{self.revision}"'), 4) - self.assertTrue(result.endswith(other)) - self.assertEqual(pin_planner(result, self.revision), result) - - def test_accepts_branch_selector(self): - """A branch-based Planner manifest can be converted to reproducible pins.""" - result = pin_planner(self.manifest.replace(f'rev = "{"b" * 40}"', 'branch = "main"'), self.revision) - self.assertEqual(result.count(f'rev = "{self.revision}"'), 4) - - def test_rejects_changed_dependency_layout(self): - """A removed dependency or missing selector requires a deliberate updater change.""" - for manifest in [self.manifest.split('\n', 1)[1], self.manifest.replace(f', rev = "{"b" * 40}"', '')]: - with self.subTest(manifest=manifest), self.assertRaises(ValueError): - pin_planner(manifest, self.revision) - - def test_rejects_invalid_revision(self): - """Branch names and truncated SHAs cannot become immutable pins.""" - for revision in ['main', 'abc123', 'z' * 40]: - with self.subTest(revision=revision), self.assertRaises(ValueError): - pin_planner(self.manifest, revision) - - -if __name__ == '__main__': - unittest.main() diff --git a/scripts/ci/update_planner.py b/scripts/ci/update_planner.py deleted file mode 100644 index 348a80a9..00000000 --- a/scripts/ci/update_planner.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -"""Pin every Planner workspace dependency to one main revision, then resolve it.""" -import re -import subprocess -from pathlib import Path - -URL = "https://github.com/ProjectASAP/ASAPPlanner" - - -def pin_planner(manifest: str, revision: str) -> str: - if not re.fullmatch(r"[0-9a-f]{40}", revision): - raise ValueError("Expected a full Planner commit SHA") - count = 0 - lines = [] - for line in manifest.splitlines(keepends=True): - if re.search(r'git\s*=\s*"' + re.escape(URL) + r'"', line): - line, replaced = re.subn(r'(?:rev|branch|tag)\s*=\s*"[^"]+"', f'rev = "{revision}"', line) - if replaced != 1: - raise ValueError("Planner dependency must have exactly one Git revision selector") - count += 1 - lines.append(line) - if count != 4: - raise ValueError(f"Expected four Planner dependencies, found {count}; review the updater") - return "".join(lines) - - -if __name__ == "__main__": - revision = subprocess.check_output( - ["git", "ls-remote", URL, "refs/heads/main"], text=True - ).split()[0] - path = Path("Cargo.toml") - original = path.read_text() - updated = pin_planner(original, revision) - if updated == original: - print(f"Planner already pinned to main: {revision}") - raise SystemExit(0) - path.write_text(updated) - subprocess.run(["cargo", "update", "-p", "asap-aware-mapping"], check=True) - print(f"Planner main: {revision}") diff --git a/scripts/sync-asapplanner-main.sh b/scripts/sync-asapplanner-main.sh new file mode 100755 index 00000000..2c2a2d97 --- /dev/null +++ b/scripts/sync-asapplanner-main.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +planner_url="https://github.com/ProjectASAP/ASAPPlanner" +planner_rev="$(git ls-remote "$planner_url" refs/heads/main | awk 'NR == 1 { print $1 }')" +if [[ ! "$planner_rev" =~ ^[0-9a-f]{40}$ ]]; then + echo "could not resolve ASAPPlanner main to a commit" >&2 + exit 1 +fi + +python3 - "$planner_rev" <<'PY' +import pathlib +import re +import sys + +path = pathlib.Path("Cargo.toml") +text = path.read_text() +revision = sys.argv[1] +pattern = re.compile( + r'(git = "https://github.com/ProjectASAP/ASAPPlanner", rev = ")[0-9a-f]{40}("\s*})' +) +updated, replacements = pattern.subn(rf"\g<1>{revision}\2", text) +if replacements != 4: + raise SystemExit(f"expected four ASAPPlanner dependencies, found {replacements}") +path.write_text(updated) +PY + +cargo update \ + -p asap-types@0.1.0 \ + -p asap-aware-mapping \ + -p asap-frontend-promql \ + -p asap-frontend-sql \ + --precise "$planner_rev" + +echo "synchronized ASAPPlanner dependencies to $planner_rev" From fdaa672df1a6a098351147c4a03b83ba708f5b87 Mon Sep 17 00:00:00 2001 From: zz_y Date: Tue, 22 Sep 2026 20:37:19 +0000 Subject: [PATCH 3/4] test: verify Planner auto-merge guards against stale and unrelated changes --- .github/workflows/mvp-ci.yml | 4 ++- .github/workflows/planner-main-merge.yml | 6 ++-- scripts/ci/README.md | 1 + scripts/ci/test_planner_merge.js | 44 ++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 scripts/ci/test_planner_merge.js diff --git a/.github/workflows/mvp-ci.yml b/.github/workflows/mvp-ci.yml index eede4217..8cfc1d22 100644 --- a/.github/workflows/mvp-ci.yml +++ b/.github/workflows/mvp-ci.yml @@ -51,7 +51,9 @@ jobs: - name: Test Planner dependency updater working-directory: ASAPQuery-backend - run: python3 -m unittest discover -s scripts/ci -p 'test_*.py' + run: | + python3 -m unittest discover -s scripts/ci -p 'test_*.py' + node scripts/ci/test_planner_merge.js - name: Check workspace formatting working-directory: ASAPQuery-backend diff --git a/.github/workflows/planner-main-merge.yml b/.github/workflows/planner-main-merge.yml index 45c882ff..cbfdcb24 100644 --- a/.github/workflows/planner-main-merge.yml +++ b/.github/workflows/planner-main-merge.yml @@ -28,8 +28,10 @@ jobs: if (prs.data.length !== 1) return; const {data: pr} = await github.rest.pulls.get({owner, repo, pull_number: prs.data[0].number}); if (pr.head.repo.full_name !== `${owner}/${repo}` || pr.head.sha !== run.head_sha || pr.draft) return; - const testedPr = run.pull_requests.find(p => p.number === pr.number); - if (!testedPr || testedPr.base.sha !== pr.base.sha) { + const {data: comparison} = await github.rest.repos.compareCommitsWithBasehead({ + owner, repo, basehead: `main...${run.head_sha}` + }); + if (comparison.merge_base_commit.sha !== comparison.base_commit.sha) { core.info('Main changed since this CI run; wait for the next updater refresh.'); return; } diff --git a/scripts/ci/README.md b/scripts/ci/README.md index 10c083eb..8c2d90e1 100644 --- a/scripts/ci/README.md +++ b/scripts/ci/README.md @@ -24,6 +24,7 @@ then run the same checks as MVP CI. Updater unit tests run with: ```sh python3 -m unittest discover -s scripts/ci -p 'test_*.py' +node scripts/ci/test_planner_merge.js ``` The sync script and scheduled workflow are shared with PR #765, at the same paths diff --git a/scripts/ci/test_planner_merge.js b/scripts/ci/test_planner_merge.js new file mode 100644 index 00000000..1c99f4ac --- /dev/null +++ b/scripts/ci/test_planner_merge.js @@ -0,0 +1,44 @@ +// Execute the privileged workflow handler with mocked GitHub responses. +const fs = require('node:fs'); +const path = require('node:path'); +const workflow = fs.readFileSync(path.join(__dirname, '../../.github/workflows/planner-main-merge.yml'), 'utf8'); +const script = workflow.split(' script: |\n')[1].split('\n').map(line => line.slice(12)).join('\n'); +const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor; +const handler = new AsyncFunction('github', 'context', 'core', script); + +async function verifyMergeGuards() { + for (const scenario of ['valid', 'stale-head', 'foreign-repo', 'draft', 'stale-main', 'extra-file', 'empty-diff', 'no-pr']) { + let merged = false; + let failed = false; + const pr = { + number: 12, + head: {repo: {full_name: scenario === 'foreign-repo' ? 'else/repo' : 'o/r'}, sha: scenario === 'stale-head' ? 'old' : 'new'}, + draft: scenario === 'draft', + }; + const github = { + rest: { + pulls: { + list: async () => ({data: scenario === 'no-pr' ? [] : [pr]}), + get: async () => ({data: pr}), + listFiles: () => {}, + merge: async args => { + if (args.sha !== 'new' || args.pull_number !== 12) throw Error('Wrong merge target'); + merged = true; + }, + }, + repos: {compareCommitsWithBasehead: async () => ({data: { + merge_base_commit: {sha: scenario === 'stale-main' ? 'old' : 'base'}, + base_commit: {sha: 'base'}, + }})}, + }, + paginate: async () => scenario === 'empty-diff' ? [] : [{filename: scenario === 'extra-file' ? 'other.rs' : 'Cargo.toml'}], + }; + await handler(github, {repo: {owner: 'o', repo: 'r'}, payload: {workflow_run: {head_sha: 'new'}}}, { + info: () => {}, setFailed: () => { failed = true; }, + }); + if (merged !== (scenario === 'valid')) throw Error(`Unexpected merge: ${scenario}`); + if (failed !== ['extra-file', 'empty-diff'].includes(scenario)) throw Error(`Unexpected failure: ${scenario}`); + } +} + +verifyMergeGuards().catch(error => { console.error(error); process.exitCode = 1; }); From e34cf8c49085e66e805036ebca0804f09a068532 Mon Sep 17 00:00:00 2001 From: zz_y Date: Tue, 22 Sep 2026 20:39:00 +0000 Subject: [PATCH 4/4] ci: leave incompatible Planner semantic upgrade to PR 761 --- Cargo.lock | 38 ++++++++++++++++++++++++++++---------- Cargo.toml | 8 ++++---- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ecdfaa3..a49ca3f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,7 +364,7 @@ dependencies = [ [[package]] name = "asap-aware-mapping" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" dependencies = [ "asap-types", "asap_sketchlib 0.3.0 (git+https://github.com/ProjectASAP/asap_sketchlib)", @@ -376,7 +376,7 @@ dependencies = [ [[package]] name = "asap-frontend-promql" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" dependencies = [ "asap-types", "promql-parser 0.10.0 (git+https://github.com/ProjectASAP/promql-parser?rev=9fede7eecca923c9882fe256484d00d37f8706cb)", @@ -385,7 +385,7 @@ dependencies = [ [[package]] name = "asap-frontend-sql" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" dependencies = [ "asap-sql-function-catalog", "asap-types", @@ -408,12 +408,12 @@ dependencies = [ [[package]] name = "asap-sql-function-catalog" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" [[package]] name = "asap-types" version = "0.1.0" -source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=2ec3fc80caa922c8e1f33aa05f60b7d787e73257#2ec3fc80caa922c8e1f33aa05f60b7d787e73257" +source = "git+https://github.com/ProjectASAP/ASAPPlanner?rev=10d93846f0ef9f06ab19e599701d699d9cdd15af#10d93846f0ef9f06ab19e599701d699d9cdd15af" dependencies = [ "serde", "serde_json", @@ -2304,6 +2304,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -2615,7 +2624,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3075,7 +3084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ "heck", - "itertools 0.13.0", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -3095,7 +3104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.119", @@ -3496,7 +3505,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4466,7 +4475,7 @@ version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" dependencies = [ - "rand 0.10.2", + "rand 0.9.5", ] [[package]] @@ -4806,6 +4815,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" diff --git a/Cargo.toml b/Cargo.toml index f59369ac..f1da29da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,10 @@ asap_sketchlib = { git = "https://github.com/ProjectASAP/asap_sketchlib", branch [workspace.dependencies] # Keep Planner frontends, selection, and IR on the same immutable revision. # Alias upstream asap-types because this workspace also defines asap_types. -planner-types = { package = "asap-types", git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } -asap-aware-mapping = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } -asap-frontend-promql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } -asap-frontend-sql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "2ec3fc80caa922c8e1f33aa05f60b7d787e73257" } +planner-types = { package = "asap-types", git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } +asap-aware-mapping = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } +asap-frontend-promql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } +asap-frontend-sql = { git = "https://github.com/ProjectASAP/ASAPPlanner", rev = "10d93846f0ef9f06ab19e599701d699d9cdd15af" } # Shared external deps (used by 2+ crates) serde = { version = "1.0", features = ["derive"] }