Skip to content

Commit f1d9bc7

Browse files
committed
Initial commit
0 parents  commit f1d9bc7

File tree

11 files changed

+352
-0
lines changed

11 files changed

+352
-0
lines changed

.github/workflows/build.yml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: Build
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
os: [ubuntu-latest, macos-latest, macos-13, windows-latest]
11+
steps:
12+
- uses: actions/setup-node@v4
13+
- uses: actions/checkout@v4
14+
- uses: esy/github-action@master
15+
with:
16+
setup-esy-npm-package: 'esy'
17+
setup-esy-version: 'latest'
18+
source-cache-key: 20240515-1
19+
cache-key: ${{ hashFiles('esy.lock/index.json') }}-20240515-1
20+
- uses: esy/github-action@master
21+
id: prepare-npm-artifacts
22+
with:
23+
source-cache-key: 20240515-1
24+
cache-key: ${{ hashFiles('esy.lock/index.json') }}-20240515-1
25+
prepare-npm-artifacts-mode: true
26+
ocaml-compiler-version: 5.1.1000
27+
ocaml-static-compiler-version: 5.1.1000
28+
29+
static-build:
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Set up Docker Buildx
33+
uses: docker/setup-buildx-action@v3
34+
- name: Build and push
35+
uses: docker/build-push-action@v5
36+
with:
37+
file: ./docker/DevImage.Dockerfile
38+
push: false
39+
tags: user/app:latest
40+
41+
bundle:
42+
permissions:
43+
contents: write
44+
needs:
45+
- build
46+
- static-build
47+
runs-on: macos-latest
48+
steps:
49+
- uses: actions/setup-node@v4
50+
with:
51+
registry-url: 'https://registry.npmjs.org'
52+
- uses: actions/checkout@v4
53+
with:
54+
fetch-depth: 100
55+
fetch-tags: true
56+
- uses: esy/github-action@master
57+
with:
58+
source-cache-key: 20240515-1
59+
cache-key: ${{ hashFiles('esy.lock/index.json') }}-20240515-1
60+
bundle-npm-artifacts-mode: true
61+
ocaml-compiler-version: 5.1.1000
62+
ocaml-static-compiler-version: 5.1.1000
63+
64+
- name: Create tarball
65+
run: tar cf npm-release.tgz ./_npm-release
66+
67+
- name: Release
68+
uses: softprops/action-gh-release@v1
69+
if: startsWith(github.ref, 'refs/tags/')
70+
with:
71+
files: npm-release.tgz
72+
73+
# - name: Publish to NPM registry
74+
# working-directory: _npm-release
75+
# run: npm publish --access=public .
76+
# env:
77+
# NODE_AUTH_TOKEN: ${{ secrets.YOUR_TOKEN_HERE }}
78+
79+
test:
80+
runs-on: ${{ matrix.os }}
81+
strategy:
82+
matrix:
83+
os: [ubuntu-latest, macos-latest, macos-13, windows-latest]
84+
needs: bundle
85+
steps:
86+
- uses: actions/setup-node@v4
87+
- uses: actions/download-artifact@v4
88+
with:
89+
name: npm-release
90+
- run: npm i --prefix $HOME/prefix -g ./npm-release.tgz
91+
if: ${{ runner.os != 'Windows' }}
92+
shell: bash
93+
- run: echo $HOME/prefix/bin >> "$GITHUB_PATH"
94+
if: ${{ runner.os != 'Windows' }}
95+
shell: bash
96+
- run: npm i -g ./npm-release.tgz
97+
if: ${{ runner.os == 'Windows' }}
98+
- run: hello
99+

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
_release
2+
_esy
3+
*~

README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test-1

docker/DevImage.Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM esydev/esy:nightly-alpine-latest
2+
3+
COPY package.json package.json
4+
COPY esy.lock esy.lock
5+
RUN esy i
6+
RUN esy build-dependencies
7+
COPY hello.ml hello.ml
8+
RUN esy
9+
10+
ENTRYPOINT ["/entrypoint.sh"]

esy.lock/.gitattributes

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esy.lock/.gitignore

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esy.lock/index.json

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hello.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let () = print_endline "hello, world :100:"

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"description": ".",
3+
"name": "@npm-handle/test-hello",
4+
"esy": {
5+
"build": [
6+
"ocamlopt -c ./hello.ml -o #{self.target_dir}/hello",
7+
"ocamlopt -o #{self.target_dir}/hello #{self.target_dir}/hello.cmx"
8+
],
9+
"install": "install #{self.target_dir}/hello #{self.bin}/hello",
10+
"release": {
11+
"bin": [
12+
"hello"
13+
]
14+
}
15+
},
16+
"dependencies": {
17+
"ocaml": "*"
18+
}
19+
}

release-postinstall.js

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/**
2+
* release-postinstall.js
3+
*
4+
* XXX: We want to keep this script installable at least with node 4.x.
5+
*
6+
* This script is bundled with the `npm` package and executed on release.
7+
* Since we have a 'fat' NPM package (with all platform binaries bundled),
8+
* this postinstall script extracts them and puts the current platform's
9+
* bits in the right place.
10+
*/
11+
12+
var path = require('path');
13+
var cp = require('child_process');
14+
var fs = require('fs');
15+
var os = require('os');
16+
var platform = process.platform;
17+
18+
var packageJson = require('./package.json');
19+
20+
function copyRecursive(srcDir, dstDir) {
21+
var results = [];
22+
var list = fs.readdirSync(srcDir);
23+
var src, dst;
24+
list.forEach(function (file) {
25+
src = path.join(srcDir, file);
26+
dst = path.join(dstDir, file);
27+
28+
var stat = fs.statSync(src);
29+
if (stat && stat.isDirectory()) {
30+
try {
31+
fs.mkdirSync(dst);
32+
} catch (e) {
33+
console.log('directory already exists: ' + dst);
34+
console.error(e);
35+
}
36+
results = results.concat(copyRecursive(src, dst));
37+
} else {
38+
try {
39+
fs.writeFileSync(dst, fs.readFileSync(src));
40+
} catch (e) {
41+
console.log("could't copy file: " + dst);
42+
console.error(e);
43+
}
44+
results.push(src);
45+
}
46+
});
47+
return results;
48+
}
49+
50+
function arch() {
51+
/**
52+
* On Windows, the most reliable way to detect a 64-bit OS from within a 32-bit
53+
* app is based on the presence of a WOW64 file: %SystemRoot%\SysNative.
54+
* See: https://twitter.com/feross/status/776949077208510464
55+
*/
56+
if (process.platform === "win32") {
57+
var useEnv = false;
58+
try {
59+
useEnv = !!(
60+
process.env.SYSTEMROOT && fs.statSync(process.env.SYSTEMROOT)
61+
);
62+
} catch (err) {}
63+
64+
var sysRoot = useEnv ? process.env.SYSTEMROOT : "C:\\Windows";
65+
66+
// If %SystemRoot%\SysNative exists, we are in a WOW64 FS Redirected application.
67+
var isWOW64 = false;
68+
try {
69+
isWOW64 = !!fs.statSync(path.join(sysRoot, "sysnative"));
70+
} catch (err) {}
71+
72+
return isWOW64 ? "x64" : "x86";
73+
}
74+
75+
/**
76+
* On Linux, use the `getconf` command to get the architecture.
77+
*/
78+
if (process.platform === "linux") {
79+
var output = cp.execSync("getconf LONG_BIT", { encoding: "utf8" });
80+
return output === "64\n" ? "x64" : "x86";
81+
}
82+
83+
/**
84+
* If none of the above, assume the architecture is 32-bit.
85+
*/
86+
return process.arch;
87+
}
88+
89+
// implementing it b/c we don't want to depend on fs.copyFileSync which appears
90+
// only in node@8.x
91+
function copyFileSync(sourcePath, destPath) {
92+
var data;
93+
try {
94+
data = fs.readFileSync(sourcePath);
95+
} catch (e) {
96+
data = fs.readFileSync(sourcePath + '.exe');
97+
sourcePath = sourcePath + '.exe';
98+
destPath = destPath + '.exe';
99+
}
100+
var stat = fs.statSync(sourcePath);
101+
fs.writeFileSync(destPath, data);
102+
fs.chmodSync(destPath, 0755);
103+
}
104+
105+
var copyPlatformBinaries = (platformPath) => {
106+
var platformBuildPath = path.join(__dirname, 'platform-esy-npm-release-' + platformPath);
107+
108+
let foldersToCopy, binariesToCopy;
109+
110+
binariesToCopy = Object.keys(packageJson.bin).map(function (name) {
111+
return packageJson.bin[name];
112+
});
113+
114+
if (platformPath === 'linux') {
115+
fs.mkdirSync(path.join(__dirname, 'lib'));
116+
foldersToCopy = ['bin', 'lib'];
117+
} else {
118+
foldersToCopy = ['bin', '_export'];
119+
binariesToCopy = binariesToCopy.concat(['esyInstallRelease.js']);
120+
}
121+
122+
foldersToCopy.forEach((folderPath) => {
123+
var sourcePath = path.join(platformBuildPath, folderPath);
124+
var destPath = path.join(__dirname, folderPath);
125+
copyRecursive(sourcePath, destPath);
126+
});
127+
128+
binariesToCopy.forEach((binaryPath) => {
129+
var sourcePath = path.join(platformBuildPath, binaryPath);
130+
var destPath = path.join(__dirname, binaryPath);
131+
if (fs.existsSync(destPath)) {
132+
fs.unlinkSync(destPath);
133+
}
134+
copyFileSync(sourcePath, destPath);
135+
});
136+
137+
if (platformPath === 'linux') {
138+
fs.chmodSync(path.join(__dirname, 'lib', 'esy', 'esyBuildPackageCommand'), 0755);
139+
fs.chmodSync(path.join(__dirname, 'lib', 'esy', 'esySolveCudfCommand'), 0755);
140+
fs.chmodSync(path.join(__dirname, 'lib', 'esy', 'esyRewritePrefixCommand'), 0755);
141+
}
142+
};
143+
144+
try {
145+
fs.mkdirSync('_export');
146+
} catch (e) {
147+
console.log('Could not create _export folder');
148+
}
149+
150+
const platformArch = arch();
151+
switch (platform) {
152+
case 'win32':
153+
if (platformArch !== 'x64') {
154+
console.warn('error: x86 is currently not supported on Windows');
155+
process.exit(1);
156+
}
157+
158+
copyPlatformBinaries('windows-x64');
159+
console.log('Installing native compiler toolchain for Windows...');
160+
cp.execSync(
161+
`npm install @prometheansacrifice/esy-bash@0.1.0-dev-f2e419601a34c3ce53cbe1f025f490276b9e879f --prefix "${__dirname}"`,
162+
);
163+
console.log('Native compiler toolchain installed successfully.');
164+
require('./esyInstallRelease');
165+
break;
166+
case 'linux':
167+
copyPlatformBinaries(`${platform}-${platformArch}`);
168+
// Statically linked binaries dont need postinstall scripts
169+
// TODO add support for statically linked binaries
170+
require('./esyInstallRelease');
171+
break;
172+
case 'darwin':
173+
copyPlatformBinaries(`${platform}-${platformArch}`);
174+
require('./esyInstallRelease');
175+
break;
176+
default:
177+
console.warn('error: no release built for the ' + platform + ' platform');
178+
process.exit(1);
179+
}

0 commit comments

Comments
 (0)