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

Compiling CLI and publishing to NPM #53

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
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
134 changes: 134 additions & 0 deletions .github/workflows/npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: Continuous Deployment

on:
push:
tags:
- 'v*.*.*'

jobs:
publish-npm-binaries:
name: Publish NPM packages
runs-on: ${{ matrix.build.os }}
strategy:
fail-fast: false
matrix:
build:
- {
NAME: linux-x64-glibc,
OS: ubuntu-20.04,
TOOLCHAIN: stable,
TARGET: x86_64-unknown-linux-gnu,
}
- {
NAME: win32-x64-msvc,
OS: windows-2022,
TOOLCHAIN: stable,
TARGET: x86_64-pc-windows-msvc,
}
- {
NAME: win32-arm64-msvc,
OS: windows-2022,
TOOLCHAIN: stable,
TARGET: aarch64-pc-windows-msvc,
}
- {
NAME: darwin-x64,
OS: macos-11,
TOOLCHAIN: stable,
TARGET: x86_64-apple-darwin,
}
- {
NAME: darwin-arm64,
OS: macos-11,
TOOLCHAIN: stable,
TARGET: aarch64-apple-darwin,
}
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Set the release version
shell: bash
run: echo "RELEASE_VERSION=${GITHUB_REF:11}" >> $GITHUB_ENV

- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.build.TOOLCHAIN }}
target: ${{ matrix.build.TARGET }}
override: true

- name: Build
uses: actions-rs/cargo@v1
with:
command: build
args: --release --target ${{ matrix.build.TARGET }}
# use-cross: ${{ matrix.build.OS == 'ubuntu-20.04' }} # use `cross` for Linux builds

- name: Install node
uses: actions/setup-node@v3
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'

- name: Publish to NPM
shell: bash
run: |
cd apps/cli/npm
# set the binary name
bin="cli"
# derive the OS and architecture from the build matrix name
# note: when split by a hyphen, first part is the OS and the second is the architecture
node_os=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f1)
export node_os
node_arch=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f2)
export node_arch
# set the version
export node_version="${{ env.RELEASE_VERSION }}"
# set the package name
# note: use 'windows' as OS name instead of 'win32'
if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
export node_pkg="${bin}-windows-${node_arch}"
else
export node_pkg="${bin}-${node_os}-${node_arch}"
fi
# create the package directory
mkdir -p "${node_pkg}/bin"
# generate package.json from the template
envsubst < package.json.tmpl > "${node_pkg}/package.json"
# copy the binary into the package
# note: windows binaries has '.exe' extension
if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
bin="${bin}.exe"
fi
cp "../../../target/${{ matrix.build.TARGET }}/release/${bin}" "${node_pkg}/bin"
# publish the package
cd "${node_pkg}"
npm publish --access public --dry-run
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

publish-npm-base:
name: Publish the base NPM package
needs: publish-npm-binaries
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install node
uses: actions/setup-node@v3
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'

- name: Publish the package
continue-on-error: true
shell: bash
run: |
cd apps/cli/npm/app
yarn install # requires optional dependencies to be present in the registry
yarn build
npm publish --access public --dry-run
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
8 changes: 5 additions & 3 deletions apps/cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "zync-cli"
name = "cli"
authors = ["[email protected]"]
version = "0.1.0"
edition = "2021"
Expand All @@ -11,8 +11,10 @@ clap = { version = "4.0.29", features = ["derive"] }
serde = {version = "1.0.145", features = ["serde_derive", "derive"]}
serde_yaml = "0.9.13"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
indoc = "1.0.7"
tokio = { version = "1", features = ["sync", "rt", "full"] }
indoc = "2.0.1"
dotenv = "0.15.0"
dotenv_codegen = "0.15.0"
convert_case = "0.6.0"
wasm-bindgen = "0.2.84"
wasm-bindgen-futures = "0.4.34"
41 changes: 41 additions & 0 deletions apps/cli/npm/app/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env node
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const child_process_1 = require('child_process');
/**
* Returns the executable path which is located inside `node_modules`
* The naming convention is app-${os}-${arch}
* If the platform is `win32` or `cygwin`, executable will include a `.exe` extension.
* @see https://nodejs.org/api/os.html#osarch
* @see https://nodejs.org/api/os.html#osplatform
* @example "x/xx/node_modules/app-darwin-arm64"
*/
function getExePath() {
const arch = process.arch;
let os = process.platform;
let extension = '';
if (['win32', 'cygwin'].includes(process.platform)) {
os = 'windows';
extension = '.exe';
}
try {
// Since the binary will be located inside `node_modules`, we can simply call `require.resolve`
return require.resolve(`@zyncli/zync-${os}-${arch}/bin/cli${extension}`);
} catch (e) {
throw new Error(
`Couldn't find application binary inside node_modules for ${os}-${arch}`,
);
}
}
/**
* Runs the application with args using nodejs spawn
*/
function run() {
var _a;
const args = process.argv.slice(2);
const processResult = (0, child_process_1.spawnSync)(getExePath(), args, {
stdio: 'inherit',
});
process.exit((_a = processResult.status) !== null && _a !== void 0 ? _a : 0);
}
run();
40 changes: 40 additions & 0 deletions apps/cli/npm/app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@zyncli/zync",
"version": "0.1.0",
"bin": "lib/index.js",
"scripts": {
"build": "tsc",
"dev": "yarn build && node lib/index.js",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "tsc --noEmit"
},
"eslintConfig": {
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"ignorePatterns": [
"lib/*"
],
"root": true
},
"devDependencies": {
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.48.0",
"eslint": "^8.31.0",
"typescript": "^4.9.4"
},
"optionalDependencies": {
"@zyncli/cli-darwin-arm64": "0.1.0",
"@zyncli/cli-darwin-x64": "0.1.0",
"@zyncli/cli-linux-x64": "0.1.0",
"@zyncli/cli-windows-arm64": "0.1.0",
"@zyncli/cli-windows-x64": "0.1.0"
}
}
41 changes: 41 additions & 0 deletions apps/cli/npm/app/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env node

import { spawnSync } from 'child_process';

/**
* Returns the executable path which is located inside `node_modules`
* The naming convention is app-${os}-${arch}
* If the platform is `win32` or `cygwin`, executable will include a `.exe` extension.
* @see https://nodejs.org/api/os.html#osarch
* @see https://nodejs.org/api/os.html#osplatform
* @example "x/xx/node_modules/app-darwin-arm64"
*/
function getExePath() {
const arch = process.arch;
let os = process.platform as string;
let extension = '';
if (['win32', 'cygwin'].includes(process.platform)) {
os = 'windows';
extension = '.exe';
}

try {
// Since the binary will be located inside `node_modules`, we can simply call `require.resolve`
return require.resolve(`@zyncli/cli-${os}-${arch}/bin/app${extension}`);
} catch (e) {
throw new Error(
`Couldn't find application binary inside node_modules for ${os}-${arch}`,
);
}
}

/**
* Runs the application with args using nodejs spawn
*/
function run() {
const args = process.argv.slice(2);
const processResult = spawnSync(getExePath(), args, { stdio: 'inherit' });
process.exit(processResult.status ?? 0);
}

run();
12 changes: 12 additions & 0 deletions apps/cli/npm/app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"baseUrl": "./",
"outDir": "lib",
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
16 changes: 16 additions & 0 deletions apps/cli/npm/package.json.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "${node_pkg}",
"version": "${node_version}",
"repository": {
"type": "git",
"url": "git+https://github.com/orhun/packaging-rust-for-npm.git"
},
"author": "Orhun Parmaksız <[email protected]>",
"homepage": "https://github.com/orhun/packaging-rust-for-npm#readme",
"os": [
"${node_os}"
],
"cpu": [
"${node_arch}"
]
}
10 changes: 5 additions & 5 deletions apps/cli/src/commands/generate.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::{
languages::{prisma::generate_prisma, typescript::generate_typescript},
utils::{config::Config, Workspace},
utils::Workspace,
ConfigFile, Generate, Language,
};

pub async fn run_generate(args: &Generate) -> Result<bool, Box<dyn std::error::Error>> {
let config = ConfigFile::new(&args.config_file_path).unwrap();

let workspace = reqwest::get(format!(
"{}/workspaces?name=First workspace",
Config::get_host()
"http://localhost:3333/api/workspaces?name={}",
config.workspace
))
.await
.expect("Couldn't make request")
Expand All @@ -19,8 +19,8 @@ pub async fn run_generate(args: &Generate) -> Result<bool, Box<dyn std::error::E

for schema in config.schemas.iter() {
match schema.1.project_type {
Language::Prisma => generate_prisma(&workspace.id, &schema.1).await,
Language::Typescript => generate_typescript(&workspace.id, &schema.1).await,
Language::Prisma => generate_prisma(&workspace.id, schema.1).await,
Language::Typescript => generate_typescript(&workspace.id, schema.1).await,
}
}
Ok(true)
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/languages/prisma.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
use crate::SystemSchema;

pub async fn generate_prisma(workspace_id: &str, schema: &SystemSchema) {}
pub async fn generate_prisma(_workspace_id: &str, _schema: &SystemSchema) {}
5 changes: 2 additions & 3 deletions apps/cli/src/languages/typescript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ use std::fs::write;
use convert_case::{Case, Casing};

use crate::{
utils::{config::Config, Class, Enum, Property, PropertyTypeRelation},
utils::{Class, Enum, Property, PropertyTypeRelation},
SystemSchema,
};

pub async fn generate_typescript(workspace_id: &str, schema: &SystemSchema) {
// Fetch all workspace classes
let classes_query = reqwest::get(format!(
"{}/workspaces/{}/classes",
Config::get_host(),
"http://localhost:3333/api/workspaces/{}/classes",
workspace_id
))
.await
Expand Down
3 changes: 2 additions & 1 deletion apps/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub struct SystemSchema {

#[derive(Debug, Deserialize)]
pub struct ConfigFile {
workspace: String,
schemas: HashMap<String, SystemSchema>,
}

Expand All @@ -68,7 +69,7 @@ impl ConfigFile {
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
let Cli::Generate(args) = Cli::parse();
run_generate(&args).await.expect("Couldn;t generate schema");
run_generate(&args).await.expect("Couldn't generate schema");

Ok(())
}
11 changes: 0 additions & 11 deletions apps/cli/src/utils/config.rs

This file was deleted.

2 changes: 0 additions & 2 deletions apps/cli/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use serde::{Deserialize, Serialize};

pub mod config;

#[derive(Default, Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
Expand Down
Loading