Skip to content

Commit 640bf47

Browse files
coadofacebook-github-bot
authored andcommitted
Publish HermesC to npm (#1754)
Summary: This diff provides a setup for publishing hermesc artifacts on `hermes-compiler` npm package from CI whenever new tag is pushed. Differential Revision: D80086333
1 parent 0c3b663 commit 640bf47

File tree

4 files changed

+140
-5
lines changed

4 files changed

+140
-5
lines changed

.github/workflows/publish.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,33 @@ jobs:
7777
- name: Copy Hermes binaries
7878
shell: bash
7979
run: |
80+
mkdir -p ./npm/hermes-compiler/hermesc/osx-bin ./npm/hermes-compiler/hermesc/win64-bin ./npm/hermes-compiler/hermesc/linux64-bin
81+
82+
# When build_hermes_macos runs as a matrix, it outputs
83+
if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then
84+
cp -r $HERMES_WS_DIR/osx-bin/Release/hermesc ./npm/hermes-compiler/hermesc/osx-bin/hermesc
85+
elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then
86+
cp -r $HERMES_WS_DIR/osx-bin/Debug/hermesc ./npm/hermes-compiler/hermesc/osx-bin/hermesc
87+
else
88+
ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing."
89+
echo "Could not locate macOS hermesc binary."; exit 1;
90+
fi
91+
92+
# Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them.
93+
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then
94+
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz"
95+
fi
96+
97+
if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then
98+
mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz"
99+
fi
100+
101+
cp -r $HERMES_WS_DIR/win64-bin/* ./npm/hermes-compiler/hermesc/win64-bin/.
102+
cp -r $HERMES_WS_DIR/linux64-bin/* ./npm/hermes-compiler/hermesc/linux64-bin/.
103+
104+
# Make sure the hermesc files are actually executable.
105+
chmod -R +x npm/hermes-compiler/hermesc/*
106+
80107
mkdir -p ./android/ios-artifacts/artifacts/
81108
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./android/ios-artifacts/artifacts/hermes-ios-debug.tar.gz
82109
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./android/ios-artifacts/artifacts/hermes-ios-release.tar.gz
@@ -93,3 +120,13 @@ jobs:
93120
shell: bash
94121
run: |
95122
node ./utils/scripts/hermes/publish-artifacts.js -t ${{ inputs.release-type }}
123+
- name: Publish to npm
124+
shell: bash
125+
run: |
126+
node ./utils/scripts/hermes/publish-npm.js -t ${{ inputs.release-type }}
127+
cp ./npm/hermes-compiler/hermes-compiler-0.12.0.tgz $HERMES_WS_DIR/hermes-compiler-0.12.0.tgz
128+
- name: Upload package
129+
uses: actions/upload-artifact@v4
130+
with:
131+
name: hermes-engine-npm
132+
path: /tmp/hermes/hermes-compiler-0.12.0.tgz

npm/hermes-compiler/package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "hermes-compiler",
3+
"version": "0.12.0",
4+
"private": false,
5+
"description": "A Hermes compiler used in React Native",
6+
"license": "MIT",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+ssh://[email protected]/facebook/hermes.git"
10+
}
11+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
/*::
14+
import type {BuildType} from './version-utils';
15+
import type { ShellString } from 'shelljs';
16+
*/
17+
18+
const {REPO_ROOT} = require('./consts');
19+
const {getVersion, validateBuildType} = require('./version-utils');
20+
const path = require('path');
21+
const {exec} = require('shelljs');
22+
const yargs = require('yargs');
23+
24+
/**
25+
* This script prepares a release version of react-native and may publish to NPM.
26+
* It is supposed to run in CI environment, not on a developer's machine.
27+
*
28+
* For a dry run, this script will:
29+
* * Version the commitly of the form `0.0.0-<commitSha>`
30+
*
31+
* For a commitly run, this script will:
32+
* * Version the commitly release of the form `0.0.0-<dateIdentifier>-<commitSha>`
33+
* * Publish to npm using `nightly` tag
34+
*
35+
* For a release run, this script will:
36+
* * Version the release by the tag version that triggered CI
37+
* * Publish to npm
38+
* * using `latest` tag if commit is currently tagged `latest`
39+
* * or otherwise `{major}.{minor}-stable`
40+
*/
41+
42+
async function main() {
43+
const argv = yargs
44+
.option('t', {
45+
alias: 'builtType',
46+
describe: 'The type of build you want to perform.',
47+
choices: ['dry-run', 'commitly', 'release'],
48+
default: 'dry-run',
49+
})
50+
.strict().argv;
51+
52+
// $FlowFixMe[prop-missing]
53+
const buildType = argv.builtType;
54+
55+
if (!validateBuildType(buildType)) {
56+
throw new Error(`Unsupported build type: ${buildType}`);
57+
}
58+
59+
const result = await publishNpm(buildType);
60+
61+
if (result && result.code) {
62+
const version = await getVersion(buildType);
63+
throw new Error(`Failed to publish hermes-compiler@${version}`);
64+
}
65+
}
66+
67+
async function publishNpm(
68+
buildType /*: BuildType */,
69+
) /*: Promise<ShellString | null> */ {
70+
if (buildType === 'dry-run') {
71+
console.log('Skipping `npm publish` because --dry-run is set.');
72+
return null;
73+
}
74+
75+
let tagFlag = '';
76+
if (buildType === 'commitly') {
77+
tagFlag = ` --tag nightly`;
78+
}
79+
80+
const otp = process.env.NPM_CONFIG_OTP;
81+
const otpFlag = otp != null ? ` --otp ${otp}` : '';
82+
const packagePath = path.join(REPO_ROOT, 'npm', 'hermes-compiler');
83+
const options = {cwd: packagePath};
84+
85+
// return exec(`npm publish${tagFlag}${otpFlag}$`, options);
86+
87+
// Pack npm only for testing to see what will be inlcuded in the package
88+
return exec('npm pack', options);
89+
}

utils/scripts/hermes/version-utils.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,17 @@ export type Version = {
1515
major: string,
1616
minor: string,
1717
patch: string,
18-
prerelease: ?string,
1918
}
2019
*/
2120

22-
const {REPO_ROOT} = require('./consts');
23-
const {ANDROID_DIR} = require('./consts');
21+
const {ANDROID_DIR, REPO_ROOT} = require('./consts');
2422
const {getCurrentCommit} = require('./scm-utils');
2523
const {promises: fs} = require('fs');
2624
const path = require('path');
2725

2826
const CMAKE_FILE_PATH = `${REPO_ROOT}/CMakeLists.txt`;
2927
const GRADLE_FILE_PATH = path.join(ANDROID_DIR, 'gradle.properties');
30-
const VERSION_REGEX =
28+
const CMAKE_VERSION_REGEX =
3129
/project\(Hermes\s+VERSION\s+(\d+\.\d+\.\d+)\s+LANGUAGES\s+C\s+CXX\)/;
3230

3331
function validateBuildType(
@@ -68,7 +66,7 @@ async function getMainVersion() /*: Promise<string> */ {
6866
}
6967

7068
function extractMatchIfValid(cmakeContent /*: string */) {
71-
const match = cmakeContent.match(VERSION_REGEX);
69+
const match = cmakeContent.match(CMAKE_VERSION_REGEX);
7270
if (!match) {
7371
throw new Error('Could not find version in CMakeLists.txt');
7472
}

0 commit comments

Comments
 (0)