Skip to content

Commit

Permalink
Fix #30: Allow installing a specific version of dub
Browse files Browse the repository at this point in the history
This needed a bit of work on the dub side, as releases were
uploaded based on the release binaries.
  • Loading branch information
Geod24 committed Jul 19, 2022
1 parent f38f3d8 commit 4a18e9f
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 27 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,44 @@ jobs:
# exclude dist/index.js.map (different on Windows)
git diff --stat --exit-code HEAD -- ':!dist/index.js.map'
shell: bash

dub:
name: Verify standalone DUB install
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, windows-latest, macOS-latest ]
dc: [ ldc-latest, dmd-latest ]
dub: [ 1.19.0, 1.23.0, 1.24.0, latest ]
exclude:
# Excluded because those are actually Linux executables
- { os: windows-latest, dub: 1.19.0 }
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Install D compiler
uses: ./
with:
compiler: ${{ matrix.dc }}
dub: ${{ matrix.dub }}

- name: Verify DUB version
shell: bash
run: |
if [[ ${{ matrix.dub }} == 'latest' ]]
then
DUB_VERSION_FOR_TEST=$(curl -s https://api.github.com/repos/dlang/dub/releases/latest | jq -r '.name | sub("v(?<v>.+)"; .v)')
else
DUB_VERSION_FOR_TEST=${{ matrix.dub }}
fi
echo "dub path is: `which dub`"
echo "dub version is: `dub --version`"
echo "We expect version: $DUB_VERSION_FOR_TEST"
if [[ "$(dub --version)" =~ "version $DUB_VERSION_FOR_TEST" ]]
then
echo "Match"
else
exit 1
fi
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,13 @@ Valid version examples are:
- `ldc-1.18.0-beta1`
- `dmd-master`
- `ldc-master`

## DUB installation

[dub](https://github.com/dlang/dub) is installed alongside the selected compiler for any versions >= v2.072.0 (2016-10-31).

If the `dub` parameter is provided to the action, this version will be the one installed instead.
Accepted parameters are 'latest', or a DUB version string (e.g. '1.29.0').

Note that DUB versions prior to v1.13.0 (DMD version v2.084.0, released 2019-01-02) do not support HTTP2,
meaning they will not work for fetching packages.
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ inputs:
compiler:
description: "Compiler version string, for example 'dmd-latest' or 'ldc-1.20.1'"
default: "dmd-latest"
dub:
description: "DUB version string, for example 'latest' or '1.29.0'"
required: false
gh_token:
description: "Token to use when doing Github API request (for ldc-master)"
default: ${{ github.token }}
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

93 changes: 72 additions & 21 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,87 @@ export interface DubDescription {
version: string;
}

export async function compiler(description: string, gh_token: string): Promise<CompilerDescription> {
export async function compiler(description: string, dub_vers: string, gh_token: string): Promise<CompilerDescription> {
const matches = description.match(/^(\w+)-(.+)$/);
if (!matches) throw new Error("invalid compiler string: " + description);

switch (matches[1]) {
case "dmd": return await dmd(matches[2]);
case "ldc": return await ldc(matches[2], gh_token);
case "dmd": return await dmd(matches[2], dub_vers, gh_token);
case "ldc": return await ldc(matches[2], dub_vers, gh_token);
default: throw new Error("unrecognized compiler: " + matches[1]);
}
}

async function legacyDub(): Promise<DubDescription> {
// download some dub version for legacy compilers not shipping dub
// this is the last version on the old download page from September 2018
async function dub(version: string, gh_token: string, legacy: boolean): Promise<DubDescription | undefined> {
// No explicit version from the user
if (!version.length) {
// We use the version bundled with the compiler
if (!legacy) return undefined;

// download some dub version for legacy compilers not shipping dub
// this is the last version on the old download page from September 2018
switch (process.platform) {
case "win32": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-windows-x86.zip"
};
case "linux": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-linux-x86_64.tar.gz"
};
case "darwin": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-osx-x86_64.tar.gz"
};
default:
throw new Error("unsupported platform: " + process.platform);
}
}

if (version === "latest") {
if (!gh_token)
throw new Error("'gh_token' parameter must be set to use dub latest version");

let json = await body_as_text(
`https://api.github.com/repos/dlang/dub/releases/latest`,
gh_token
);
let rname = JSON.parse(json)["name"];
if (rname == undefined) {
console.log(json)
throw new Error("Couldn't load release name for dub latest version");
}
console.log("Using DUB latest version: ", rname);
version = rname;
}

const matches = version.match(/^v?(1\.\d+\.\d+)(-.+)?$/);
if (!matches)
throw new Error("unrecognized DUB version: '" + version +
"'. Make sure to use the dub version, and not the frontend one.");
if (matches[2])
throw new Error("only release versions of DUB are supported, not: " + version)
version = "v" + matches[1];

switch (process.platform) {
case "win32": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-windows-x86.zip"
version: version,
url: `https://github.com/dlang/dub/releases/download/${version}/dub-${version}-windows-x86_64.zip`
};
case "linux": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-linux-x86_64.tar.gz"
version: version,
url: `https://github.com/dlang/dub/releases/download/${version}/dub-${version}-linux-x86_64.tar.gz`
};
case "darwin": return {
version: "1.11.0",
url: "https://code.dlang.org/files/dub-1.11.0-osx-x86_64.tar.gz"
version: version,
url: `https://github.com/dlang/dub/releases/download/${version}/dub-${version}-osx-x86_64.tar.gz`
};
default:
throw new Error("unsupported platform: " + process.platform);
}
}

async function dmd(version: string): Promise<CompilerDescription> {
async function dmd(version: string, dub_vers: string, gh_token: string): Promise<CompilerDescription> {
let beta = false;

switch (version) {
Expand Down Expand Up @@ -83,7 +131,7 @@ async function dmd(version: string): Promise<CompilerDescription> {
: beta ? `http://downloads.dlang.org/pre-releases/2.x/${folder}/dmd.${version}`
: `http://downloads.dlang.org/releases/2.x/${folder}/dmd.${version}`;

const dub = (minor !== undefined && minor < 72) ? await legacyDub() : undefined;
const legacy = (minor !== undefined && minor < 72);

switch (process.platform) {
case "win32": return {
Expand All @@ -94,7 +142,7 @@ async function dmd(version: string): Promise<CompilerDescription> {
: `${base_url}.windows.7z`,
binpath: "\\dmd2\\windows\\bin",
libpath: [ "\\dmd2\\windows\\bin64" ],
dub: dub,
dub: await dub(dub_vers, gh_token, legacy),
// Signatures for nightly releases are not available (yet?)
sig: nightly ? undefined : `${base_url}.windows.7z.sig`
};
Expand All @@ -106,7 +154,7 @@ async function dmd(version: string): Promise<CompilerDescription> {
: `${base_url}.linux.tar.xz`,
binpath: "/dmd2/linux/bin64",
libpath: [ "/dmd2/linux/lib64" ],
dub: dub,
dub: await dub(dub_vers, gh_token, legacy),
sig: nightly ? undefined : `${base_url}.linux.tar.xz.sig`
};
case "darwin": return {
Expand All @@ -117,7 +165,7 @@ async function dmd(version: string): Promise<CompilerDescription> {
: `${base_url}.osx.tar.xz`,
binpath: "/dmd2/osx/bin",
libpath: [ "/dmd2/linux/lib64" ],
dub: dub,
dub: await dub(dub_vers, gh_token, legacy),
sig: nightly ? undefined : `${base_url}.osx.tar.xz.sig`
};
default:
Expand Down Expand Up @@ -185,7 +233,7 @@ async function ldc_resolve_master(gh_token: string): Promise<CompilerDescription
};
}

async function ldc(version: string, gh_token: string): Promise<CompilerDescription> {
async function ldc(version: string, dub_vers: string, gh_token: string): Promise<CompilerDescription> {
switch (version) {
case "latest":
version = await body_as_text("https://ldc-developers.github.io/LATEST");
Expand All @@ -208,21 +256,24 @@ async function ldc(version: string, gh_token: string): Promise<CompilerDescripti
version: version,
url: `${base_url}-windows-multilib.7z`,
binpath: `\\ldc2-${version}-windows-multilib\\bin`,
libpath: [ `\\ldc2-${version}-windows-multilib\\lib64` ]
libpath: [ `\\ldc2-${version}-windows-multilib\\lib64` ],
dub: await dub(dub_vers, gh_token, false)
};
case "linux": return {
name: "ldc2",
version: version,
url: `${base_url}-linux-x86_64.tar.xz`,
binpath: `/ldc2-${version}-linux-x86_64/bin`,
libpath: [ `/ldc2-${version}-linux-x86_64/lib64` ]
libpath: [ `/ldc2-${version}-linux-x86_64/lib64` ],
dub: await dub(dub_vers, gh_token, false)
};
case "darwin": return {
name: "ldc2",
version: version,
url: `${base_url}-osx-x86_64.tar.xz`,
binpath: `/ldc2-${version}-osx-x86_64/bin`,
libpath: [ `/ldc2-${version}-osx-x86_64/lib64` ]
libpath: [ `/ldc2-${version}-osx-x86_64/lib64` ],
dub: await dub(dub_vers, gh_token, false)
};
default:
throw new Error("unsupported platform: " + process.platform);
Expand Down
23 changes: 19 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import { mkdirP } from '@actions/io';
import { rmRF } from '@actions/io';
import * as gpg from './gpg';

import { compiler } from './compiler';
Expand All @@ -12,11 +12,15 @@ async function run() {

const input = core.getInput('compiler') || "dmd-latest";
const gh_token = core.getInput('gh_token') || "";
const descr = await compiler(input, gh_token);
const dub_version = core.getInput('dub') || "";
const descr = await compiler(input, dub_version, gh_token);

console.log(`Enabling ${input}`);
if (dub_version.length)
console.log(`Enabling ${input} with dub ${dub_version}`);
else
console.log(`Enabling ${input}`);

const cache_tag = descr.name + "-" + descr.version + (descr.dub ? descr.dub.version : "");
const cache_tag = descr.name + "-" + descr.version + (descr.dub ? "+dub-" + descr.dub.version : "");

let cached = tc.find('dc', cache_tag);

Expand All @@ -35,7 +39,18 @@ async function run() {
const dc_path = await extract(descr.url, archive);

if (descr.dub) {
console.log(`Downloading ${descr.dub.url}`);
const archive2 = await tc.downloadTool(descr.dub.url);
// Required on Windows, other archive tools don't mind the override
if (process.platform === "win32") {
console.log("Removing: " + dc_path + descr.binpath + "\\dub.exe");
await rmRF(dc_path + descr.binpath + "\\dub.exe");
await descr.libpath.forEach(function(libpath) {
const path = dc_path + libpath;
console.log("Removing: " + path + "\\dub.exe");
return rmRF(path + "\\dub.exe");
});
}
await extract(descr.dub.url, archive2, dc_path + descr.binpath);
}

Expand Down

0 comments on commit 4a18e9f

Please sign in to comment.