CodeSampleX

Beispiel

electron-publish 25.1.7: Publish artifacts with electron-publish Publisher

Verifiziertes Beispiel für npm electron-publish 25.1.7: Publish artifacts with electron-publish Publisher. Der Vertrag lief auf node 22 · linux alpine/x64 …

sha256:85e832c5d4234ffdb79e8a1757d1557c88a8e0a0e5c0b1b09f24fd8bd9b73e5e

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
1
Signaturschlüssel, die es gebaut haben
1
Deklarierte Umgebung node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-08-27

Fall

HOW
Ziel
Publish artifacts with electron-publish Publisher
Pakete
Umgebung
node 22.23.2
Erstellt
2026-08-27T17:06:23Z

Contract

  1. Publisher provides an extensible base class for artifact publishing with providerName and upload methods
  2. HttpPublisher handles artifact uploads via doUpload with support for in-memory buffers and file stat sizing
  3. HttpPublisher uses safeArtifactName when configured and falls back to target file basename
  4. getCiTag parses CI environment tags or returns null when no tag environment variable is set

Dateien

  • PROMPT.md
  • csx.json
  • index.js
  • package-lock.json
  • package.json
  • spec.json
  • test/contract.cjs

Quellartefakt herunterladen (tar.gz)

Quelltext

PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: Publish artifacts with electron-publish Publisher
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/electron-publish@25.1.7
Constraints:
  - executionContext: node
Required runtime conditions:
  - ecosystem: npm
  - language: javascript
  - moduleSystem: cjs
  - packageManager: npm@10.9.8
  - runtime: node@22.23.2

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:5bb139e5f971943a2d143aa0e96282dc1b3f9a842b001ab8650dff8980d371d6","constraints":{"executionContext":"node"},"contract":["Publisher provides an extensible base class for artifact publishing with providerName and upload methods","HttpPublisher handles artifact uploads via doUpload with support for in-memory buffers and file stat sizing","HttpPublisher uses safeArtifactName when configured and falls back to target file basename","getCiTag parses CI environment tags or returns null when no tag environment variable is set"],"goal":"Publish artifacts with electron-publish Publisher","kind":"HOW","packages":["pkg:npm/electron-publish@25.1.7"],"schemaVersion":1},"contractCommand":["node","test/contract.cjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"cjs","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/electron-publish@25.1.7"],"schemaVersion":1,"subject":"pkg:npm/electron-publish@25.1.7","verifierAdapter":"node-typescript@1"}
index.js
'use strict';

const { Publisher, HttpPublisher, getCiTag } = require('electron-publish');

/**
 * In-memory custom publisher extending the base Publisher.
 */
class MemoryPublisher extends Publisher {
  constructor(context) {
    super(context);
    this.uploadedTasks = [];
  }

  get providerName() {
    return 'custom-memory';
  }

  async upload(task) {
    const result = {
      uploaded: true,
      file: task.file,
      arch: task.arch,
      safeArtifactName: task.safeArtifactName || null,
      provider: this.providerName
    };
    this.uploadedTasks.push(result);
    return result;
  }

  toString() {
    return 'MemoryPublisher';
  }
}

/**
 * Mock HTTP publisher extending the base HttpPublisher.
 */
class MockHttpPublisher extends HttpPublisher {
  constructor(context, useSafeArtifactName = false) {
    super(context, useSafeArtifactName);
    this.uploads = [];
  }

  get providerName() {
    return 'mock-http';
  }

  async doUpload(fileName, arch, dataLength, requestProcessor, file) {
    const uploadRecord = {
      fileName,
      arch,
      dataLength,
      file
    };
    this.uploads.push(uploadRecord);
    return uploadRecord;
  }

  toString() {
    return 'MockHttpPublisher';
  }
}

module.exports = {
  Publisher,
  HttpPublisher,
  getCiTag,
  MemoryPublisher,
  MockHttpPublisher
};
package-lock.json
{
  "name": "sample-239259010",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample-239259010",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "electron-publish": "25.1.7"
      }
    },
    "node_modules/@types/debug": {
      "version": "4.1.13",
      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz",
      "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==",
      "license": "MIT",
      "dependencies": {
        "@types/ms": "*"
      }
    },
    "node_modules/@types/fs-extra": {
      "version": "9.0.13",
      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
      "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
      "license": "MIT",
      "dependencies": {
        "@types/node": "*"
      }
    },
    "node_modules/@types/ms": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
      "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
      "license": "MIT"
    },
    "node_modules/@types/node": {
      "version": "26.4.0",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
      "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~8.3.0"
      }
    },
    "node_modules/7zip-bin": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz",
      "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==",
      "license": "MIT"
    },
    "node_modules/agent-base": {
      "version": "7.1.4",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
      "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
      "license": "MIT",
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "license": "MIT",
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/app-builder-bin": {
      "version": "5.0.0-alpha.10",
      "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.10.tgz",
      "integrity": "sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw==",
      "license": "MIT"
    },
    "node_modules/argparse": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
      "license": "Python-2.0"
    },
    "node_modules/async-exit-hook": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
      "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
      "license": "MIT",
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/bluebird": {
      "version": "3.7.2",
      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
      "license": "MIT"
    },
    "node_modules/bluebird-lst": {
      "version": "1.0.9",
      "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz",
      "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==",
      "license": "MIT",
      "dependencies": {
        "bluebird": "^3.5.5"
      }
    },
    "node_modules/buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "license": "MIT"
    },
    "node_modules/builder-util": {
      "version": "25.1.7",
      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-25.1.7.tgz",
      "integrity": "sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww==",
      "license": "MIT",
      "dependencies": {
        "@types/debug": "^4.1.6",
        "7zip-bin": "~5.2.0",
        "app-builder-bin": "5.0.0-alpha.10",
        "bluebird-lst": "^1.0.9",
        "builder-util-runtime": "9.2.10",
        "chalk": "^4.1.2",
        "cross-spawn": "^7.0.3",
        "debug": "^4.3.4",
        "fs-extra": "^10.1.0",
        "http-proxy-agent": "^7.0.0",
        "https-proxy-agent": "^7.0.0",
        "is-ci": "^3.0.0",
        "js-yaml": "^4.1.0",
        "source-map-support": "^0.5.19",
        "stat-mode": "^1.0.0",
        "temp-file": "^3.4.0"
      }
    },
    "node_modules/builder-util-runtime": {
      "version": "9.2.10",
      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz",
      "integrity": "sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==",
      "license": "MIT",
      "dependencies": {
        "debug": "^4.3.4",
        "sax": "^1.2.4"
      },
      "engines": {
        "node": ">=12.0.0"
      }
    },
    "node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "license": "MIT",
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/ci-info": {
      "version": "3.9.0",
      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/sibiraj-s"
        }
      ],
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "license": "MIT",
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "license": "MIT"
    },
    "node_modules/cross-spawn": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
      "license": "MIT",
      "dependencies": {
        "path-key": "^3.1.0",
        "shebang-command": "^2.0.0",
        "which": "^2.0.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/debug": {
      "version": "4.4.3",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.3"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/electron-publish": {
      "version": "25.1.7",
      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-25.1.7.tgz",
      "integrity": "sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==",
      "license": "MIT",
      "dependencies": {
        "@types/fs-extra": "^9.0.11",
        "builder-util": "25.1.7",
        "builder-util-runtime": "9.2.10",
        "chalk": "^4.1.2",
        "fs-extra": "^10.1.0",
        "lazy-val": "^1.0.5",
        "mime": "^2.5.2"
      }
    },
    "node_modules/fs-extra": {
      "version": "10.1.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
      "license": "MIT",
      "dependencies": {
        "graceful-fs": "^4.2.0",
        "jsonfile": "^6.0.1",
        "universalify": "^2.0.0"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
      "license": "ISC"
    },
    "node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/http-proxy-agent": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
      "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
      "license": "MIT",
      "dependencies": {
        "agent-base": "^7.1.0",
        "debug": "^4.3.4"
      },
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/https-proxy-agent": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
      "license": "MIT",
      "dependencies": {
        "agent-base": "^7.1.2",
        "debug": "4"
      },
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/is-ci": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
      "license": "MIT",
      "dependencies": {
        "ci-info": "^3.2.0"
      },
      "bin": {
        "is-ci": "bin.js"
      }
    },
    "node_modules/isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
      "license": "ISC"
    },
    "node_modules/js-yaml": {
      "version": "4.3.2",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
      "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/puzrin"
        },
        {
          "type": "github",
          "url": "https://github.com/sponsors/nodeca"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "argparse": "^2.0.1"
      },
      "bin": {
        "js-yaml": "bin/js-yaml.js"
      }
    },
    "node_modules/jsonfile": {
      "version": "6.2.1",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
      "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
      "license": "MIT",
      "dependencies": {
        "universalify": "^2.0.0"
      },
      "optionalDependencies": {
        "graceful-fs": "^4.1.6"
      }
    },
    "node_modules/lazy-val": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
      "license": "MIT"
    },
    "node_modules/mime": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
      "license": "MIT",
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/ms": {
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "license": "MIT"
    },
    "node_modules/path-key": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/sax": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
      "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
      "license": "BlueOak-1.0.0",
      "engines": {
        "node": ">=11.0.0"
      }
    },
    "node_modules/shebang-command": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
      "license": "MIT",
      "dependencies": {
        "shebang-regex": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/shebang-regex": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "license": "BSD-3-Clause",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/source-map-support": {
      "version": "0.5.21",
      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
      "license": "MIT",
      "dependencies": {
        "buffer-from": "^1.0.0",
        "source-map": "^0.6.0"
      }
    },
    "node_modules/stat-mode": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
      "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
      "license": "MIT",
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "license": "MIT",
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/temp-file": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz",
      "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==",
      "license": "MIT",
      "dependencies": {
        "async-exit-hook": "^2.0.1",
        "fs-extra": "^10.0.0"
      }
    },
    "node_modules/undici-types": {
      "version": "8.3.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
      "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
      "license": "MIT"
    },
    "node_modules/universalify": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
      "license": "MIT",
      "engines": {
        "node": ">= 10.0.0"
      }
    },
    "node_modules/which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "license": "ISC",
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "node-which": "bin/node-which"
      },
      "engines": {
        "node": ">= 8"
      }
    }
  }
}
package.json
{
  "name": "sample-electron-publish",
  "version": "1.0.0",
  "private": true,
  "description": "Publish artifacts with electron-publish Publisher",
  "main": "index.js",
  "scripts": {
    "test": "node test/contract.cjs"
  },
  "dependencies": {
    "electron-publish": "25.1.7"
  },
  "license": "MIT-0"
}
spec.json
{
  "schemaVersion": 1,
  "goal": "Publish artifacts with electron-publish Publisher",
  "kind": "HOW",
  "packages": [
    "pkg:npm/electron-publish@25.1.7"
  ],
  "constraints": {
    "executionContext": "node"
  },
  "runtimeConditions": {
    "ecosystem": "npm",
    "language": "javascript",
    "moduleSystem": "cjs",
    "packageManager": "npm@10.9.8",
    "runtime": "node@22.23.2"
  }
}
test/contract.cjs
'use strict';

const assert = require('assert');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { Publisher, HttpPublisher, getCiTag, MemoryPublisher, MockHttpPublisher } = require('../index.js');

async function run() {
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'electron-publish-contract-'));
  const testArtifact = path.join(tmpDir, 'app-build-linux-x64.zip');

  try {
    const dummyContent = 'electron publish sample artifact content';
    fs.writeFileSync(testArtifact, dummyContent, 'utf8');

    const fakeContext = {
      cancellationToken: {
        isCancelled: false,
        createPromise: () => new Promise(() => {})
      },
      progress: null
    };

    // 1. Verify Publisher base class and custom implementation
    assert.strictEqual(typeof Publisher, 'function', 'Publisher must be a class constructor');
    const memoryPub = new MemoryPublisher(fakeContext);
    assert.strictEqual(memoryPub.providerName, 'custom-memory', 'providerName must return custom provider');
    assert.strictEqual(memoryPub.toString(), 'MemoryPublisher', 'toString must return class identifier');

    const memTask = {
      file: testArtifact,
      arch: 1, // Arch.x64
      safeArtifactName: 'custom-dist.zip'
    };
    const memResult = await memoryPub.upload(memTask);
    assert.strictEqual(memResult.uploaded, true, 'MemoryPublisher.upload must resolve upload status');
    assert.strictEqual(memResult.file, testArtifact, 'MemoryPublisher.upload must preserve target file');
    assert.strictEqual(memoryPub.uploadedTasks.length, 1, 'MemoryPublisher must record upload task');

    // 2. Verify HttpPublisher base class with in-memory buffer
    assert.strictEqual(typeof HttpPublisher, 'function', 'HttpPublisher must be a class constructor');
    const httpPub = new MockHttpPublisher(fakeContext, false);
    assert.strictEqual(httpPub.providerName, 'mock-http', 'providerName must return mock-http');

    const bufferPayload = Buffer.from('in-memory-binary-data', 'utf8');
    await httpPub.upload({
      file: '/path/to/virtual-artifact.tar.gz',
      fileContent: bufferPayload,
      arch: 1
    });

    assert.strictEqual(httpPub.uploads.length, 1, 'HttpPublisher must record buffer upload');
    assert.strictEqual(httpPub.uploads[0].fileName, 'virtual-artifact.tar.gz', 'HttpPublisher must use basename by default');
    assert.strictEqual(httpPub.uploads[0].dataLength, bufferPayload.length, 'HttpPublisher must pass buffer length');

    // 3. Verify HttpPublisher with safeArtifactName enabled
    const safeHttpPub = new MockHttpPublisher(fakeContext, true);
    await safeHttpPub.upload({
      file: testArtifact,
      arch: 1,
      safeArtifactName: 'safe-dist-name.zip'
    });

    assert.strictEqual(safeHttpPub.uploads.length, 1, 'safeHttpPub must record file upload');
    assert.strictEqual(safeHttpPub.uploads[0].fileName, 'safe-dist-name.zip', 'HttpPublisher must respect safeArtifactName when enabled');
    assert.strictEqual(safeHttpPub.uploads[0].dataLength, Buffer.byteLength(dummyContent, 'utf8'), 'HttpPublisher must pass stat size for file');

    // 4. Verify getCiTag environment resolution
    assert.strictEqual(typeof getCiTag, 'function', 'getCiTag must be exported as a function');

    const originalEnv = {
      GITHUB_REF_TYPE: process.env.GITHUB_REF_TYPE,
      GITHUB_REF_NAME: process.env.GITHUB_REF_NAME,
      TRAVIS_TAG: process.env.TRAVIS_TAG,
      CIRCLE_TAG: process.env.CIRCLE_TAG
    };

    // Clean env tags
    delete process.env.GITHUB_REF_TYPE;
    delete process.env.GITHUB_REF_NAME;
    delete process.env.TRAVIS_TAG;
    delete process.env.CIRCLE_TAG;
    delete process.env.APPVEYOR_REPO_TAG_NAME;
    delete process.env.BITRISE_GIT_TAG;
    delete process.env.CI_BUILD_TAG;
    delete process.env.CI_COMMIT_TAG;
    delete process.env.BITBUCKET_TAG;

    assert.strictEqual(getCiTag(), null, 'getCiTag must return null when no CI tag is present');

    process.env.GITHUB_REF_TYPE = 'tag';
    process.env.GITHUB_REF_NAME = 'v1.0.0';
    assert.strictEqual(getCiTag(), 'v1.0.0', 'getCiTag must resolve GitHub tag ref');

    delete process.env.GITHUB_REF_TYPE;
    delete process.env.GITHUB_REF_NAME;
    process.env.TRAVIS_TAG = 'v2.5.0';
    assert.strictEqual(getCiTag(), 'v2.5.0', 'getCiTag must resolve Travis tag');

    // Restore env
    for (const [k, v] of Object.entries(originalEnv)) {
      if (v === undefined) {
        delete process.env[k];
      } else {
        process.env[k] = v;
      }
    }

    console.log('Contract tests passed successfully.');
    process.exit(0);
  } finally {
    try {
      if (fs.existsSync(tmpDir)) {
        fs.rmSync(tmpDir, { recursive: true, force: true });
      }
    } catch (e) {
      // Ignore cleanup error
    }
  }
}

run().catch((err) => {
  console.error('Contract test failed:', err);
  process.exit(1);
});

Ursprungs-Seeder

anonym