Repository: denoland/deno_core
Pull request #482 (2024-01-24 23:43:48)

feat(core): add resources to stats test


Patch:
diff --git a/.cargo/config.toml b/.cargo/config.toml
deleted file mode 100644
index fa11555..0000000
--- a/.cargo/config.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[registries]
-# Specify the registry as "upstream" so we can dry-run publish to a test server
-upstream = { index = "sparse+https://index.crates.io/" }
diff --git a/.github/workflows/ci-job.yml b/.github/workflows/ci-job.yml
index b2489d6..d2ddb34 100644
--- a/.github/workflows/ci-job.yml
+++ b/.github/workflows/ci-job.yml
@@ -11,6 +11,12 @@ on:
       job:
         required: true
         type: string
+      is_main:
+        required: true
+        type: boolean
+      is_tag:
+        required: true
+        type: boolean
 
 jobs:
   job:
@@ -33,12 +39,17 @@ jobs:
         with:
           prefix-key: "v0-rust"
           shared-key: "${{ inputs.label }}-${{ inputs.job }}"
-          save-if: ${{ github.ref == 'refs/heads/main' }}
+          save-if: ${{ inputs.is_main }}
 
       - name: Clean
-        if: github.ref == 'refs/heads/main'
+        if: inputs.is_main
         run: cargo clean
 
+      - name: No-op
+        id: nop
+        if: inputs.job == 'nop'
+        uses: ./.github/workflows/ci-nop
+
       - name: Lint
         id: lint
         if: inputs.job == 'lint'
@@ -64,6 +75,11 @@ jobs:
         if: inputs.job == 'test-miri'
         uses: ./.github/workflows/ci-test-miri
 
+      - name: Publish (dry-run)
+        id: test-publish
+        if: inputs.job == 'test-publish'
+        uses: ./.github/workflows/ci-test-publish
+
       - name: Publish
         id: publish
         if: inputs.job == 'publish'
diff --git a/.github/workflows/ci-nop/action.yml b/.github/workflows/ci-nop/action.yml
new file mode 100644
index 0000000..26421a3
--- /dev/null
+++ b/.github/workflows/ci-nop/action.yml
@@ -0,0 +1,7 @@
+name: No-op
+runs:
+  using: "composite"
+  steps:
+    - name: No-op
+      shell: bash
+      run: echo 'Doing nothing (intentionally)!'
diff --git a/.github/workflows/ci-publish/action.yml b/.github/workflows/ci-publish/action.yml
index 9c4c6c9..b0d840b 100644
--- a/.github/workflows/ci-publish/action.yml
+++ b/.github/workflows/ci-publish/action.yml
@@ -2,25 +2,8 @@ name: Publish workflow
 runs:
   using: "composite"
   steps:
-    - name: Cargo publish (dry-run)
-      shell: bash
-      if: contains(github.event.pull_request.labels.*.name, 'cargo-publish-dry-run')
-      env:
-        CARGO_REGISTRIES_UPSTREAM_INDEX: sparse+http://localhost:8000/api/v1/crates/
-        CARGO_REGISTRIES_UPSTREAM_TOKEN: Zy9HhJ02RJmg0GCrgLfaCVfU6IwDfhXD
-        # This should match our bumped-up crates.io limits
-        KELLNR_REGISTRY__MAX_CRATE_SIZE: 10
-      run: |
-        curl -L --output kellnr-latest.zip "https://github.com/kellnr/kellnr/releases/download/v5.1.1/kellnr-x86_64-unknown-linux-gnu.zip"
-        unzip kellnr-latest.zip -d ./kellnr
-        (cd ./kellnr && ./kellnr) &
-        sleep 1
-        for package in serde_v8 deno_ops deno_core; do
-          cargo publish -p $package --registry upstream --allow-dirty
-        done
     - name: Cargo publish
       shell: bash
-      if: "!contains(github.event.pull_request.labels.*.name, 'cargo-publish-dry-run')"
       run: |
         for package in serde_v8 deno_ops deno_core; do
           cargo publish -p $package
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a8000b1..09f4051 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,19 +1,29 @@
 name: CI
 
-on: [push, pull_request]
+on:
+  # Run on any push to main or any tag
+  push:
+    branches:
+      - main
+    tags:
+      - \*
+  # Run on any pull request
+  pull_request:
+    branches:
+      - main
 
 jobs:
-  success:
-    needs: top
-    runs-on: ubuntu-latest
-    steps:
-      - name: Print success
-        run: echo Success ✅
-
   compute-jobs:
     runs-on: ubuntu-latest
     outputs:
-      matrix: ${{ steps.read-jobs.outputs.matrix }}
+      # If we're not running in the denoland repo, or we're building on a tag, use the 'nop' matrix
+      # that runs a single, no-op job
+      matrix: |
+        ${{ (github.repository == 'denoland/deno_core' && !startsWith(github.ref, 'refs/tags/')) 
+          && steps.read-jobs.outputs.matrix 
+          || '[{ "label": "linux", "os": "ubuntu-latest", "job": "nop" }]' }}
+      is_tag: ${{ github.repository == 'denoland/deno_core' && startsWith(github.ref, 'refs/tags/') }}
+      is_main: ${{ github.repository == 'denoland/deno_core' && github.ref == 'refs/heads/main' }}
     steps:
       # https://github.com/marketplace/actions/query-yaml-config-as-outputs
       - name: Read job configuration
@@ -27,7 +37,7 @@ jobs:
           config: |-
             linux:
               os: ubuntu-latest
-              jobs: [lint, lint-deps, test, test-miri, test-ops]
+              jobs: [lint, lint-deps, test, test-miri, test-ops, test-publish]
             macos:
               os: macOS-latest
               jobs: [lint, test]
@@ -38,23 +48,35 @@ jobs:
   top:
     name: build-${{ matrix.label }}
     needs: compute-jobs
-    if: github.repository == 'denoland/deno_core'
     uses: ./.github/workflows/ci-job.yml
     with:
       label: ${{ matrix.label }}
       os: ${{ matrix.os }}
       job: ${{ matrix.job }}
+      is_main: ${{ needs.compute-jobs.outputs.is_main == true }}
+      is_tag: ${{ needs.compute-jobs.outputs.is_tag == true }}
     strategy:
       matrix:
         include: ${{ fromJSON(needs.compute-jobs.outputs.matrix) }}
 
+  success:
+    needs: top
+    runs-on: ubuntu-latest
+    steps:
+      - name: Print success
+        run: echo Success ✅
+
   publish:
     name: publish
-    needs: top
-    if: (github.repository == 'denoland/deno_core' && startsWith(github.ref, 'refs/tags/')) || contains(github.event.pull_request.labels.*.name, 'cargo-publish-dry-run')
+    needs:
+      - top
+      - compute-jobs
+    if: needs.compute-jobs.outputs.is_tag
     uses: ./.github/workflows/ci-job.yml
     secrets: inherit
     with:
       label: linux
       os: ubuntu-latest
       job: publish
+      is_main: ${{ needs.compute-jobs.outputs.is_main }}
+      is_tag: ${{ needs.compute-jobs.outputs.is_tag }}
diff --git a/serde_v8/utilities/Cargo.toml b/serde_v8/utilities/Cargo.toml
index a8a3dd6..0c38207 100644
--- a/serde_v8/utilities/Cargo.toml
+++ b/serde_v8/utilities/Cargo.toml
@@ -3,6 +3,7 @@
 [package]
 name = "serde_v8_utilities"
 version = "0.3.0"
+publish = false
 
 [lib]
 path = "lib.rs"
diff --git a/tools/deno_core_workspace.ts b/tools/deno_core_workspace.ts
index 347da7b..872ec76 100644
--- a/tools/deno_core_workspace.ts
+++ b/tools/deno_core_workspace.ts
@@ -27,6 +27,10 @@ export class DenoWorkspace {
     return this.#repo;
   }
 
+  static get manifest() {
+    return $.path.join(this.rootDirPath, "Cargo.toml");
+  }
+
   get crates() {
     return this.#repo.crates;
   }
@@ -34,7 +38,7 @@ export class DenoWorkspace {
   /** Gets the deno_core dependency crates that should be published. */
   getDenoCoreDependencyCrates() {
     return this.getDenoCoreCrate()
-      .descendantDependenciesInRepo();
+      .immediateDependenciesInRepo().map(c => c.crate);
   }
 
   getDenoCoreCrate() {
diff --git a/tools/publish_dry_run.ts b/tools/publish_dry_run.ts
new file mode 100755
index 0000000..0647d11
--- /dev/null
+++ b/tools/publish_dry_run.ts
@@ -0,0 +1,40 @@
+#!/usr/bin/env -S deno run -A --lock=tools/deno.lock.json
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+import { DenoWorkspace } from "./deno_core_workspace.ts";
+
+const workspace = await DenoWorkspace.load();
+const repo = workspace.repo;
+const denoCoreCrate = workspace.getDenoCoreCrate();
+
+const allCrates = {};
+allCrates[denoCoreCrate.name] = denoCoreCrate;
+
+for (const crate of workspace.getDenoCoreDependencyCrates()) {
+  allCrates[crate.name] = crate;
+}
+
+// We have the crates in the correct publish order here
+const cratesInOrder = repo.getCratesPublishOrder().map(c => allCrates[c.name]).filter(c => !!c);
+
+for (const crate of cratesInOrder) {
+  await crate.increment("minor");
+}
+
+const originalManifest = Deno.readTextFileSync(DenoWorkspace.manifest);
+let manifest = originalManifest;
+for (const crate of cratesInOrder) {
+  const re = new RegExp(`^(\\b${crate.name}\\b\\s=.*)}$`, "gm");
+  manifest = manifest.replace(re, '$1, registry = "upstream" }');
+}
+
+Deno.writeTextFileSync(DenoWorkspace.manifest, manifest);
+
+for (const crate of cratesInOrder) {
+  await crate.publish(
+    "-p", crate.name,
+    "--allow-dirty", 
+    "--registry", "upstream",
+    "--token", "Zy9HhJ02RJmg0GCrgLfaCVfU6IwDfhXD", 
+    "--config", 'registries.upstream.index="sparse+http://localhost:8000/api/v1/crates/"'
+  );
+}


Test patch:
diff --git a/.github/workflows/ci-test-publish/action.yml b/.github/workflows/ci-test-publish/action.yml
new file mode 100644
index 0000000..d24f870
--- /dev/null
+++ b/.github/workflows/ci-test-publish/action.yml
@@ -0,0 +1,17 @@
+name: Test publish
+runs:
+  using: "composite"
+  steps:
+    - name: Cargo publish (dry-run)
+      shell: bash
+      env:
+        CARGO_REGISTRIES_UPSTREAM_INDEX: sparse+http://localhost:8000/api/v1/crates/
+        CARGO_REGISTRIES_UPSTREAM_TOKEN: Zy9HhJ02RJmg0GCrgLfaCVfU6IwDfhXD
+        # This should match our bumped-up crates.io limits
+        KELLNR_REGISTRY__MAX_CRATE_SIZE: 10
+      run: |
+        curl -L --output kellnr-latest.zip "https://github.com/kellnr/kellnr/releases/download/v5.1.1/kellnr-x86_64-unknown-linux-gnu.zip"
+        unzip kellnr-latest.zip -d ./kellnr
+        (cd ./kellnr && ./kellnr) &
+        sleep 1
+        tools/publish_dry_run.ts
diff --git a/testing/checkin/runtime/async.ts b/testing/checkin/runtime/async.ts
index e17be2b..d075394 100644
--- a/testing/checkin/runtime/async.ts
+++ b/testing/checkin/runtime/async.ts
@@ -74,21 +74,30 @@ export class StatsDiff {
   }
 }
 
+// This contains an array of serialized RuntimeActivity structs.
 export class StatsCollection {
   // deno-lint-ignore no-explicit-any
   constructor(private data: any[]) {
   }
 
-  countOps(): number {
+  private countResourceActivity(type: string): number {
     let count = 0;
     for (const item of this.data) {
-      if ("AsyncOp" in item) {
+      if (type in item) {
         count++;
       }
     }
     return count;
   }
 
+  countOps(): number {
+    return this.countResourceActivity("AsyncOp");
+  }
+
+  countResources(): number {
+    return this.countResourceActivity("Resource");
+  }
+
   get empty(): boolean {
     return this.data.length == 0;
   }
diff --git a/testing/unit/resource_test.ts b/testing/unit/resource_test.ts
index 37f69c0..44ddf21 100644
--- a/testing/unit/resource_test.ts
+++ b/testing/unit/resource_test.ts
@@ -13,7 +13,10 @@ test(async function testPipe() {
 
 test(async function testPipeSmallRead() {
   const [p1, p2] = op_pipe_create();
-  assertEquals(6, await Deno.core.write(p1, new Uint8Array([1, 2, 3, 4, 5, 6])));
+  assertEquals(
+    6,
+    await Deno.core.write(p1, new Uint8Array([1, 2, 3, 4, 5, 6])),
+  );
   const buf = new Uint8Array(1);
   for (let i = 1; i <= 6; i++) {
     assertEquals(1, await Deno.core.read(p2, buf));
diff --git a/testing/unit/stats_test.ts b/testing/unit/stats_test.ts
index d8919b3..4da84a4 100644
--- a/testing/unit/stats_test.ts
+++ b/testing/unit/stats_test.ts
@@ -2,6 +2,8 @@
 import { barrierAwait, barrierCreate, StatsFactory } from "checkin:async";
 import { assert, assertEquals, test } from "checkin:testing";
 
+const { op_pipe_create } = Deno.core.ensureFastOps();
+
 test(async function testStatsOps() {
   using statsBefore = StatsFactory.capture();
   assert(statsBefore.dump().empty);
@@ -22,3 +24,19 @@ test(async function testStatsOps() {
   const diff = StatsFactory.diff(statsBefore, statsAfter);
   assert(diff.empty);
 });
+
+test(function testStatsResources() {
+  using statsBefore = StatsFactory.capture();
+
+  const [p1, p2] = op_pipe_create();
+  using statsMiddle = StatsFactory.capture();
+  const diffMiddle = StatsFactory.diff(statsBefore, statsMiddle);
+  assertEquals(0, diffMiddle.disappeared.countResources());
+  assertEquals(2, diffMiddle.appeared.countResources());
+  Deno.core.close(p1);
+  Deno.core.close(p2);
+
+  using statsAfter = StatsFactory.capture();
+  const diff = StatsFactory.diff(statsBefore, statsAfter);
+  assert(diff.empty);
+});