Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix doxygen installation on older MacOS + feat: use Node 20 in GitHub Actions + support dmg setup #232

Merged
merged 15 commits into from
Feb 19, 2024
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@ jobs:
- windows-2019
- ubuntu-22.04
- ubuntu-20.04
- macos-13
- macos-12
- macos-11
node:
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ Setting up a **cross-platform** environment for building and testing C++/C proje

`setup-cpp` can be used locally from terminal, from CI services like GitHub Actions and GitLab Pipelines, and inside containers like Docker.

`setup-cpp` is supported on many platforms. It is continuously tested on several configurations including Windows (11, 10, 2022, 2019), Linux (Ubuntu 22.04, Ubuntu 20.04, Fedora, ArchLinux), and macOS (12, 11, 10.15). `setup-cpp` is backed by unit tests for each tool and integration tests for compiling cpp projects.
`setup-cpp` is supported on many platforms. It is continuously tested on several configurations including Windows (11, 10, 2022, 2019), Linux (Ubuntu 22.04, Ubuntu 20.04, Fedora, ArchLinux), and macOS (13, 12, 11, 10.15). `setup-cpp` is backed by unit tests for each tool and integration tests for compiling cpp projects.

## Features

2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ inputs:
required: false

runs:
using: "node16"
using: "node20"
main: "dist/actions/setup-cpp.js"

branding:
3 changes: 3 additions & 0 deletions dist/actions/actions_python.10530df8.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/actions/actions_python.10530df8.js.map

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions dist/actions/actions_python.bfd29453.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/actions/actions_python.bfd29453.js.map

This file was deleted.

2 changes: 2 additions & 0 deletions dist/actions/hdi.89f0ed6f.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/actions/hdi.89f0ed6f.js.map

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions dist/actions/setup-cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/actions/setup-cpp.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dist/legacy/actions_python.7877377d.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/legacy/actions_python.7877377d.js.map

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions dist/legacy/actions_python.c7411d6b.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/legacy/actions_python.c7411d6b.js.map

This file was deleted.

2 changes: 2 additions & 0 deletions dist/legacy/hdi.069dd8f5.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/legacy/hdi.069dd8f5.js.map

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions dist/legacy/setup-cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/legacy/setup-cpp.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dist/modern/actions_python.4fb6b558.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/modern/actions_python.4fb6b558.js.map

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions dist/modern/actions_python.6be0dfa4.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/modern/actions_python.6be0dfa4.js.map

This file was deleted.

2 changes: 2 additions & 0 deletions dist/modern/hdi.9d60a332.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/modern/hdi.9d60a332.js.map

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions dist/modern/setup-cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/modern/setup-cpp.js.map

Large diffs are not rendered by default.

30 changes: 14 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@
"build": "run-s clean build.packages && run-p lint.tsc build.parcel copy.matchers",
"build.packages": "pnpm run -r build",
"build.parcel": "cross-env NODE_ENV=production parcel build && babel ./dist --out-dir dist --plugins @upleveled/babel-plugin-remove-node-prefix --compact --no-babelrc --source-maps true",
"bump": "ncu -u -x numerous,execa,prettier && pnpm update",
"bump": "ncu -u -x numerous,execa,prettier,@types/node && pnpm update",
"clean": "shx rm -rf ./dist ./exe ./packages/*/dist/ && shx mkdir -p ./dist/legacy ./dist/actions ./dist/modern ",
"copy.matchers": "run-p copy.matchers.legacy copy.matchers.actions copy.matchers.modern",
"copy.matchers.legacy": "shx cp ./src/gcc/gcc_matcher.json ./dist/legacy/ && shx cp ./src/msvc/msvc_matcher.json ./dist/legacy/ && shx cp ./src/python/python_matcher.json ./dist/legacy/ && shx cp ./src/llvm/llvm_matcher.json ./dist/legacy/",
@@ -75,15 +75,16 @@
"@actions/exec": "^1.1.1",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"@babel/cli": "^7.23.4",
"@swc/jest": "^0.2.31",
"@babel/cli": "^7.23.9",
"@shockpkg/archive-files": "https://github.com/aminya/archive-files#54ec59fad46aca736ac6feb6c7bb526528141b9d",
"@swc/jest": "^0.2.36",
"@types/cross-spawn": "^6.0.6",
"@types/eslint": "^8.56.2",
"@types/jest": "^29.5.11",
"@types/jest": "^29.5.12",
"@types/mri": "^1.1.5",
"@types/node": "^20.11.5",
"@types/node": "^12",
"@types/prettier": "2.7.3",
"@types/semver": "^7.5.6",
"@types/semver": "^7.5.7",
"@types/which": "^3.0.3",
"@upleveled/babel-plugin-remove-node-prefix": "github:aminya/babel-plugin-remove-node-prefix#95fcbd92405b99a6eece48c493548996f12e6519",
"admina": "^1.0.1",
@@ -102,12 +103,13 @@
"execa": "^7.2.0",
"is-url-online": "^1.5.0",
"jest": "^29.7.0",
"macos-release": "^3.2.0",
"micro-memoize": "^4.1.2",
"mkdirp": "^3.0.1",
"mri": "^1.2.0",
"msvc-dev-cmd": "github:aminya/msvc-dev-cmd#97843d525947e3f3776ee359b597316909754c4d",
"npm-check-updates": "^16.14.12",
"npm-run-all2": "^6.1.1",
"npm-check-updates": "^16.14.15",
"npm-run-all2": "^6.1.2",
"numerous": "1.0.3",
"p-timeout": "^6.1.2",
"parcel": "2.11.0",
@@ -117,7 +119,7 @@
"prettier-config-atomic": "^4.0.0",
"readme-md-generator": "^1.0.0",
"retry-as-promised": "^7.0.4",
"semver": "7.5.4",
"semver": "7.6.0",
"setup-python": "github:aminya/setup-python#a783db655c6e40317e2c0c96f9d162d9c9f4a751",
"shx": "0.3.4",
"simple-update-notifier": "^2.0.0",
@@ -184,12 +186,8 @@
"electron": false,
"patha": "patha/dist/index.node.mjs",
"admina": "admina/dist/index.mjs",
"fs/promises": "./src/utils/compat/fs/promises.ts"
},
"pnpm": {
"overrides": {
"@actions/http-client": "2.1.0"
}
"fs/promises": "./src/utils/compat/fs/promises.ts",
"stream/promises": "./src/utils/compat/stream/promises.ts"
},
"targets": {
"main": {
@@ -206,7 +204,7 @@
"actions": {
"context": "node",
"engines": {
"node": ">=16.x"
"node": ">=20.x"
},
"includeNodeModules": {
"update-notifier": false
1,465 changes: 820 additions & 645 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/doxygen/__tests__/doxygen.test.ts
Original file line number Diff line number Diff line change
@@ -4,9 +4,15 @@ import { InstallationInfo } from "../../utils/setup/setupBin"
import { getVersion } from "../../versions/versions"
import which from "which"
import { ubuntuVersion } from "../../utils/env/ubuntu_version"
import { macosVersion } from "../../utils/env/macos_version"

jest.setTimeout(300000)
describe("setup-doxygen", () => {
if (process.platform === "darwin" && macosVersion()[0] <= 11) {
test.skip("Skipping doxygen test on macOS 11 or earlier", () => {})
return
}

let directory: string
beforeAll(async () => {
directory = await setupTmpDir("doxygen")
29 changes: 27 additions & 2 deletions src/doxygen/doxygen.ts
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@ import { isUbuntu } from "../utils/env/isUbuntu"
import { pathExists } from "path-exists"
import retry from "retry-as-promised"
import { ubuntuVersion } from "../utils/env/ubuntu_version"
import { macosVersion } from "../utils/env/macos_version"
import { setupDmg } from "../utils/setup/setupDmg"

/** Get the platform data for cmake */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -42,6 +44,16 @@ function getDoxygenPackageInfo(version: string, platform: NodeJS.Platform, _arch
url: `https://www.doxygen.nl/files/${folderName}.windows.x64.bin.zip`,
}
}
case "darwin": {
const folderName = `Doxygen-${version}`
return {
binRelativeDir: "Doxygen/Doxygen.app/Contents/Resources/",
binFileName: addExeExt("doxygen"),
extractedFolderName: folderName,
extractFunction: setupDmg,
url: `https://doxygen.nl/files/${folderName}.dmg`,
}
}
default:
throw new Error(`Unsupported platform '${platform}'`)
}
@@ -63,8 +75,17 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
return installationInfo
}
case "darwin": {
// let installationInfo: InstallationInfo
// try {
// installationInfo = await setupBin("doxygen", version, getDoxygenPackageInfo, setupDir, arch)
// } catch {
const installationInfo = await setupBrewPack("doxygen", undefined)
await setupGraphviz(getVersion("graphviz", undefined), "", arch)
// }

// only install graphviz if the macOS version is greater than 11
if (macosVersion()[0] > 11) {
await setupGraphviz(getVersion("graphviz", undefined), "", arch)
}
return installationInfo
}
case "linux": {
@@ -83,7 +104,11 @@ export async function setupDoxygen(version: string, setupDir: string, arch: stri
try {
// doxygen on stable Ubuntu repositories is very old. So, we use get the binary from the website itself
installationInfo = await setupBin("doxygen", version, getDoxygenPackageInfo, setupDir, arch)
await setupAptPack([{ name: "libclang-cpp9" }])
try {
await setupAptPack([{ name: "libclang-cpp9" }])
} catch (err) {
info(`Failed to download libclang-cpp9 that might be needed for running doxygen. ${err}`)
}
} catch (err) {
notice(`Failed to download doxygen binary. ${err}. Falling back to apt-get.`)
installationInfo = await setupAptPack([{ name: "doxygen" }])
6 changes: 6 additions & 0 deletions src/graphviz/__tests__/graphviz.test.ts
Original file line number Diff line number Diff line change
@@ -3,9 +3,15 @@ import { cleanupTmpDir, setupTmpDir, testBin } from "../../utils/tests/test-help
import { InstallationInfo } from "../../utils/setup/setupBin"
import { getVersion } from "../../versions/versions"
import { ubuntuVersion } from "../../utils/env/ubuntu_version"
import { macosVersion } from "../../utils/env/macos_version"

jest.setTimeout(300000)
describe("setup-graphviz", () => {
if (process.platform === "darwin" && macosVersion()[0] <= 11) {
test.skip("Skipping graphviz test on macOS 11 or earlier", () => {})
return
}

let directory: string
beforeAll(async () => {
directory = await setupTmpDir("graphviz")
16 changes: 13 additions & 3 deletions src/utils/compat/fs/promises.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { promises } from "fs"
export default promises
import * as fs from "fs"
export default fs.promises

export const {
access,
@@ -26,4 +26,14 @@ export const {
unlink,
utimes,
writeFile,
} = promises
} = fs.promises

import { promisify } from "util"
export const rm =
"rm" in fs.promises
? (
fs.promises as typeof fs.promises & {
rm: (path: string, options?: fs.RmDirOptions) => Promise<void>
}
).rm
: promisify(fs.unlink)
15 changes: 15 additions & 0 deletions src/utils/compat/stream/promises.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */

import * as stream from "stream"
import { promisify } from "util"

export const pipeline =
"promises" in stream && "pipeline" in (stream as any).promises
? ((stream.promises as any).pipeline as Function)
: promisify(stream.pipeline)

export const finished =
"promises" in stream && "finished" in (stream as any).promises
? ((stream.promises as any).finished as Function)
: promisify(stream.finished)
17 changes: 17 additions & 0 deletions src/utils/env/macos_version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import macosRelease from "macos-release"
import memoize from "micro-memoize"

/**
* Get macOS version
*
* @returns {number[]} - The macOS version as an array of numbers
*/
function macosVersion_raw() {
if (process.platform !== "darwin") {
return []
}

const { version } = macosRelease()
return version.split(".").map((v) => parseInt(v, 10))
}
export const macosVersion = memoize(macosVersion_raw)
4 changes: 4 additions & 0 deletions src/utils/env/ubuntu_version.ts
Original file line number Diff line number Diff line change
@@ -38,6 +38,10 @@ export const ubuntuVersion = memoize(ubuntuVersion_raw, { isPromise: true })

/** Detect Ubuntu version using os.version() for Ubuntu based distros */
function detectUsingOsVersion() {
if (!("version" in os && typeof os.version === "function")) {
return null
}

// #46~22.04.1-Ubuntu SMP ...
const osVersion = os.version()
const versionSplitted = osVersion.split(".")
3 changes: 3 additions & 0 deletions src/utils/setup/archive-files.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "@shockpkg/archive-files/esm/archive/hdi.mjs" {
export { ArchiveHdi } from "@shockpkg/archive-files/dts/archive/hdi.d.ts"
}
3 changes: 3 additions & 0 deletions src/utils/setup/setupAptPack.ts
Original file line number Diff line number Diff line change
@@ -235,6 +235,9 @@ export async function isPackageInstalled(regexp: string) {
try {
// check if a package matching the regexp is installed
const { stdout } = await execa("dpkg", ["-l", regexp])
if (typeof stdout !== "string") {
return false
}
const lines = stdout.split("\n")
// check if the output contains any lines that start with "ii"
return lines.some((line) => line.startsWith("ii"))
2 changes: 1 addition & 1 deletion src/utils/setup/setupBin.ts
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ export type PackageInfo = {
binFileName: string
/** The function to extract the downloaded archive. It can be `undefined`, if the binary itself is downloaded directly. */
extractFunction?: {
(file: string, dest: string): Promise<string> | Promise<void>
(file: string, dest: string): Promise<unknown>
}
}

10 changes: 10 additions & 0 deletions src/utils/setup/setupDmg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { join } from "path"

export async function setupDmg(path: string, destDir: string) {
const { ArchiveHdi } = await import("@shockpkg/archive-files/esm/archive/hdi.mjs")

const dmg = new ArchiveHdi(path)
await dmg.read(async (entry) => {
await entry.extract(join(destDir, entry.path))
})
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -17,7 +17,8 @@
"preserveSymlinks": true,
"removeComments": false,
"skipLibCheck": true,
"lib": ["ES2020", "dom"],
// target Node.js 12 https://node.green/#ES2019
"lib": ["ES2019", "dom"],
"target": "ESNext",
"allowJs": true,
"esModuleInterop": true,

Unchanged files with check annotations Beta

if (isUbuntu()) {
promises.push(
updateAptAlternatives("cc", `${binDir}/gcc-${majorVersion}`, priority),

Check warning on line 226 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("cxx", `${binDir}/g++-${majorVersion}`, priority),

Check warning on line 227 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("gcc", `${binDir}/gcc-${majorVersion}`, priority),

Check warning on line 228 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("g++", `${binDir}/g++-${majorVersion}`, priority),

Check warning on line 229 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
)
}
} else {
if (isUbuntu()) {
promises.push(
updateAptAlternatives("cc", `${binDir}/gcc-${version}`, priority),

Check warning on line 237 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("cxx", `${binDir}/g++-${version}`, priority),

Check warning on line 238 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("gcc", `${binDir}/gcc-${version}`, priority),

Check warning on line 239 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
updateAptAlternatives("g++", `${binDir}/g++-${version}`, priority),

Check warning on line 240 in src/gcc/gcc.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Unsafe argument of type `Promise<any>` assigned to a parameter of type `Promise<void | ExecaReturnValue<string>>`
)
}
}
expect(process.env.CXX?.includes("clang++")).toBeTruthy()
// test compilation
const file = path.join(__dirname, "main.cpp")

Check warning on line 92 in src/llvm/__tests__/llvm.test.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Caution: `path` also has a named export `join`. Check if you meant to write `import {join} from 'patha'` instead
const main_exe = path.join(__dirname, addExeExt("main"))

Check warning on line 93 in src/llvm/__tests__/llvm.test.ts

GitHub Actions / Build (ubuntu-22.04, 20, 8)

Caution: `path` also has a named export `join`. Check if you meant to write `import {join} from 'patha'` instead
execaSync("clang++", [file, "-o", main_exe], { cwd: __dirname })
if (process.platform !== "win32") {
chmodSync(main_exe, "755")