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
77 changes: 42 additions & 35 deletions .github/workflows/ci.yml → .github/workflows/ci.generated.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,51 @@
name: CI
# GENERATED BY ./ci.ts -- DO NOT DIRECTLY EDIT

name: CI
on:
pull_request:
branches: [main]
branches:
- main
push:
branches: [main]
branches:
- main
tags:
- "*"

- '*'
jobs:
build:
name: test_release
runs-on: macos-14

permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v6
- uses: denoland/setup-deno@v2
- uses: actions/setup-dotnet@v5
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2
- uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5
with:
dotnet-version: "10.0.x"

dotnet-version: 10.0.x
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22.x
registry-url: 'https://registry.npmjs.org'
- name: Build (Debug)
run: dotnet build DprintPluginRoslyn

- name: Test
run: dotnet test

- name: Test Exe
run: cd test && cargo test

- name: Build (Release)
run: |
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime win-x64
run: |-
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime osx-x64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime osx-arm64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime linux-x64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime linux-musl-x64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime linux-arm64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime linux-musl-arm64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime osx-x64
dotnet build DprintPluginRoslyn -c Release --self-contained --runtime osx-arm64

dotnet build DprintPluginRoslyn -c Release --self-contained --runtime win-x64
- name: Package
run: |
run: |-
RELEASE_DIR=$GITHUB_WORKSPACE/DprintPluginRoslyn/bin/Release/net10.0
# cd to each output directory so we only include its files
cd $RELEASE_DIR/osx-x64
zip -r ../../../../../dprint-plugin-roslyn-x86_64-apple-darwin.zip ./*
cd $RELEASE_DIR/osx-arm64
Expand All @@ -60,28 +62,27 @@ jobs:
zip -r ../../../../../dprint-plugin-roslyn-x86_64-pc-windows-msvc.zip ./*
- name: Create plugin file
run: deno run --allow-read=. --allow-write=. scripts/create_plugin_file.ts

- name: Get tag version
if: startsWith(github.ref, 'refs/tags/')
id: get_tag_version
run: echo ::set-output name=TAG_VERSION::${GITHUB_REF/refs\/tags\//}

if: 'startsWith(github.ref, ''refs/tags/'')'
run: 'echo TAG_VERSION=${GITHUB_REF/refs\/tags\//} >> $GITHUB_OUTPUT'
- name: Get plugin file checksum
if: startsWith(github.ref, 'refs/tags/')
id: get_plugin_file_checksum
run: echo "::set-output name=CHECKSUM::$(shasum -a 256 plugin.json | awk '{print $1}')"

if: 'startsWith(github.ref, ''refs/tags/'')'
run: 'echo "CHECKSUM=$(shasum -a 256 plugin.json | awk ''{print $1}'')" >> $GITHUB_OUTPUT'
- name: Build npm packages
if: 'startsWith(github.ref, ''refs/tags/'')'
run: deno run -A scripts/create_npm_packages.ts
- name: Create release notes
if: startsWith(github.ref, 'refs/tags/')
run: deno run -A ./scripts/generate_release_notes.ts ${{ steps.get_tag_version.outputs.TAG_VERSION }} ${{ steps.get_plugin_file_checksum.outputs.CHECKSUM }} > ${{ github.workspace }}-CHANGELOG.txt

if: 'startsWith(github.ref, ''refs/tags/'')'
run: 'deno run -A ./scripts/generate_release_notes.ts ${{ steps.get_tag_version.outputs.TAG_VERSION }} ${{ steps.get_plugin_file_checksum.outputs.CHECKSUM }} > ${{ github.workspace }}-CHANGELOG.txt'
- name: Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
if: startsWith(github.ref, 'refs/tags/')
if: 'startsWith(github.ref, ''refs/tags/'')'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
with:
files: |
files: |-
dprint-plugin-roslyn-x86_64-apple-darwin.zip
dprint-plugin-roslyn-aarch64-apple-darwin.zip
dprint-plugin-roslyn-x86_64-unknown-linux-gnu.zip
Expand All @@ -90,5 +91,11 @@ jobs:
dprint-plugin-roslyn-aarch64-unknown-linux-musl.zip
dprint-plugin-roslyn-x86_64-pc-windows-msvc.zip
plugin.json
body_path: ${{ github.workspace }}-CHANGELOG.txt
body_path: '${{ github.workspace }}-CHANGELOG.txt'
draft: false
- name: Upgrade npm
if: 'startsWith(github.ref, ''refs/tags/'')'
run: npm install --global npm@latest
- name: Publish npm packages
if: 'startsWith(github.ref, ''refs/tags/'')'
run: deno run -A scripts/publish_npm_packages.ts
138 changes: 138 additions & 0 deletions .github/workflows/ci.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/usr/bin/env -S deno run -A
import { conditions, step, workflow } from "jsr:@david/gagen@^0.5.0";

const pluginName = "dprint-plugin-roslyn";

interface Profile {
/** dprint platform identifier */
platform: string;
/** dotnet --runtime value */
dotnetRuntime: string;
/** rust target triple used in the zip name */
target: string;
}

const profiles: Profile[] = [
{ platform: "darwin-x86_64", dotnetRuntime: "osx-x64", target: "x86_64-apple-darwin" },
{ platform: "darwin-aarch64", dotnetRuntime: "osx-arm64", target: "aarch64-apple-darwin" },
{ platform: "linux-x86_64", dotnetRuntime: "linux-x64", target: "x86_64-unknown-linux-gnu" },
{ platform: "linux-x86_64-musl", dotnetRuntime: "linux-musl-x64", target: "x86_64-unknown-linux-musl" },
{ platform: "linux-aarch64", dotnetRuntime: "linux-arm64", target: "aarch64-unknown-linux-gnu" },
{ platform: "linux-aarch64-musl", dotnetRuntime: "linux-musl-arm64", target: "aarch64-unknown-linux-musl" },
{ platform: "windows-x86_64", dotnetRuntime: "win-x64", target: "x86_64-pc-windows-msvc" },
];

const isTag = conditions.isTag();

const zipFor = (p: Profile) => `${pluginName}-${p.target}.zip`;

const getTagVersion = step({
id: "get_tag_version",
name: "Get tag version",
if: isTag,
run: "echo TAG_VERSION=${GITHUB_REF/refs\\/tags\\//} >> $GITHUB_OUTPUT",
outputs: ["TAG_VERSION"],
});

const getPluginFileChecksum = step({
id: "get_plugin_file_checksum",
name: "Get plugin file checksum",
if: isTag,
run: `echo "CHECKSUM=$(shasum -a 256 plugin.json | awk '{print $1}')" >> $GITHUB_OUTPUT`,
outputs: ["CHECKSUM"],
});

workflow({
name: "CI",
on: {
pull_request: { branches: ["main"] },
push: { branches: ["main"], tags: ["*"] },
},
jobs: [{
id: "build",
name: "test_release",
runsOn: "macos-14",
// id-token: write is required for npm --provenance
permissions: { contents: "write", "id-token": "write" },
steps: [
{ name: "Checkout", uses: "actions/checkout@v6" },
{ uses: "denoland/setup-deno@v2" },
{
uses: "actions/setup-dotnet@v5",
with: { "dotnet-version": "10.0.x" },
},
{
uses: "actions/setup-node@v4",
with: { "node-version": "22.x", "registry-url": "https://registry.npmjs.org" },
},
{
name: "Build (Debug)",
run: "dotnet build DprintPluginRoslyn",
},
{ name: "Test", run: "dotnet test" },
{ name: "Test Exe", run: "cd test && cargo test" },
{
name: "Build (Release)",
run: profiles.map((p) =>
`dotnet build DprintPluginRoslyn -c Release --self-contained --runtime ${p.dotnetRuntime}`
),
},
{
name: "Package",
// cd into each output directory so we only include its files
run: [
"RELEASE_DIR=$GITHUB_WORKSPACE/DprintPluginRoslyn/bin/Release/net10.0",
...profiles.flatMap((p) => [
`cd $RELEASE_DIR/${p.dotnetRuntime}`,
`zip -r ../../../../../${zipFor(p)} ./*`,
]),
],
},
{
name: "Create plugin file",
run: "deno run --allow-read=. --allow-write=. scripts/create_plugin_file.ts",
},
getTagVersion,
getPluginFileChecksum,
{
// must run before "Create release notes" — the notes embed the main
// npm tarball's sha256 from npm-dist/publish-manifest.json.
name: "Build npm packages",
if: isTag,
run: "deno run -A scripts/create_npm_packages.ts",
},
{
name: "Create release notes",
if: isTag,
run:
`deno run -A ./scripts/generate_release_notes.ts ${getTagVersion.outputs.TAG_VERSION} ${getPluginFileChecksum.outputs.CHECKSUM} > \${{ github.workspace }}-CHANGELOG.txt`,
},
{
name: "Release",
if: isTag,
uses: "softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844",
env: { GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" },
with: {
files: [...profiles.map(zipFor), "plugin.json"].join("\n"),
body_path: "${{ github.workspace }}-CHANGELOG.txt",
draft: false,
},
},
{
// npm trusted publishing (OIDC) requires npm >= 11.5.1.
name: "Upgrade npm",
if: isTag,
run: "npm install --global npm@latest",
},
{
name: "Publish npm packages",
if: isTag,
run: "deno run -A scripts/publish_npm_packages.ts",
},
],
}],
}).writeOrLint({
filePath: new URL("./ci.generated.yml", import.meta.url),
header: "# GENERATED BY ./ci.ts -- DO NOT DIRECTLY EDIT",
pinDeps: true,
});
95 changes: 95 additions & 0 deletions scripts/create_npm_packages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env -S deno run -A
import { getChecksum, processPlugin } from "jsr:@dprint/automation@0.11.3";
import $ from "jsr:@david/dax@^0.47.0";

const pluginName = "dprint-plugin-roslyn";
const mainPackageName = "@dprint/roslyn";
const outDir = "npm-dist";
// where the platform zips are extracted before being repacked as npm sub-packages.
const extractDir = "npm-binaries";

const platforms: processPlugin.Platform[] = [
"darwin-x86_64",
"darwin-aarch64",
"linux-x86_64",
"linux-x86_64-musl",
"linux-aarch64",
"linux-aarch64-musl",
"windows-x86_64",
];

const rootDir = $.path(import.meta.dirname!).join("..");
const version = extractVersionFromCsproj(
await rootDir.join("DprintPluginRoslyn/DprintPluginRoslyn.csproj").readText(),
);

const extractRoot = rootDir.join(extractDir);
extractRoot.mkdirSync({ recursive: true });

const platformInputs = await Promise.all(platforms.map(async (platform) => {
const zipPath = rootDir.join(
processPlugin.getStandardZipFileName(pluginName, platform),
);
const platformDir = extractRoot.join(platform);
platformDir.mkdirSync({ recursive: true });
await $`unzip -o ${zipPath.toString()} -d ${platformDir.toString()}`.quiet();
const binaryName = platform.startsWith("windows-") ? `${pluginName}.exe` : pluginName;
return {
platform,
binaryPath: platformDir.join(binaryName).toString(),
// roslyn is a self-contained .NET app — the executable references ~200
// sibling DLLs and runtime files, so we ship the whole dir.
packageContents: platformDir.toString(),
};
}));

const result = await processPlugin.createDprintOrgNpmPackages({
pluginName,
mainPackageName,
version,
outDir: rootDir.join(outDir).toString(),
platforms: platformInputs,
packageJsonExtra: {
description: "Use Roslyn (the .NET compiler) as a dprint plugin to format C# and VB code.",
license: "MIT",
repository: {
type: "git",
url: "git+https://github.com/dprint/dprint-plugin-roslyn.git",
},
homepage: "https://github.com/dprint/dprint-plugin-roslyn",
},
});

// hash the main tarball so the release-notes step can embed it in the
// `npm:@dprint/roslyn@<version>/plugin.json@<hash>` reference users paste
// into dprint.json. This is the hash dprint verifies before extracting.
const mainPackageChecksum = await getChecksum(await Deno.readFile(result.mainPackageTarball));

// emit a manifest so publish_npm_packages.ts knows the order and which
// tarballs to publish without having to re-derive it from the directory.
await Deno.writeTextFile(
rootDir.join(outDir, "publish-manifest.json").toString(),
JSON.stringify(
{
mainPackageName,
version,
subPackageTarballs: result.subPackageTarballs,
mainPackageTarball: result.mainPackageTarball,
mainPackageChecksum,
},
undefined,
2,
) + "\n",
);

console.log("Main package tarball:", result.mainPackageTarball);
console.log("Sub-package tarballs:");
for (const tgz of result.subPackageTarballs) {
console.log(" " + tgz);
}

function extractVersionFromCsproj(text: string): string {
const match = text.match(/<Version>(\d+\.\d+\.\d+)<\/Version>/);
if (!match) throw new Error("Could not find <Version>X.Y.Z</Version> in .csproj");
return match[1];
}
Loading
Loading