Skip to content

Commit

Permalink
Add JavaScript package.
Browse files Browse the repository at this point in the history
  • Loading branch information
whitequark committed Dec 22, 2023
1 parent c09bae5 commit d39139e
Show file tree
Hide file tree
Showing 38 changed files with 662 additions and 81 deletions.
190 changes: 113 additions & 77 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,109 +26,119 @@ jobs:
uses: actions/cache@v3
with:
path: ~/.cache/ccache
key: ${{ runner.os }}-
key: nextpnr-${{ hashFiles('nextpnr-src', 'icestorm-src', 'prjtrellis-src', 'prjoxide-src', 'apycula-meta', 'build.sh') }}
restore-keys: |
nextpnr-${{ hashFiles('nextpnr-src', 'icestorm-src', 'prjtrellis-src', 'prjoxide-src', 'apycula-meta', 'build.sh') }}
nextpnr-
- name: Set up ccache
run: |
ccache --max-size=2G -z
- name: Build WASM binaries
run: |
./build.sh
- name: Build iCE40 binary wheels
- name: Build Python artifacts
run: |
./package-pypi-ice40.sh
- name: Upload iCE40 binary wheel artifact
uses: actions/upload-artifact@v3
with:
name: wheel
path: pypi-ice40/dist/
- name: Test iCE40 binary wheels
run: |
pip install pypi-ice40/dist/*.whl
yowasp-icepll -h || true
yowasp-icebram -h || true
yowasp-icemulti -h || true
yowasp-icepack -h || true
yowasp-iceunpack -h || true
yowasp-nextpnr-ice40 --help
yowasp-nextpnr-ice40 --hx8k --package ct256 --test
yowasp-nextpnr-ice40 --up5k --package sg48 --test
- name: Build ECP5 binary wheels
run: |
./package-pypi-ecp5.sh
- name: Upload ECP5 binary wheel artifact
uses: actions/upload-artifact@v3
with:
name: wheel
path: pypi-ecp5/dist/
- name: Test ECP5 binary wheels
run: |
pip install pypi-ecp5/dist/*.whl
yowasp-ecppll --help || true
yowasp-ecpbram --help
yowasp-ecpmulti --help || true
yowasp-ecppack --help || true
yowasp-ecpunpack --help || true
yowasp-nextpnr-ecp5 --help
yowasp-nextpnr-ecp5 --um5g-25k --package CABGA381 --test
- name: Build MachXO2 binary wheels
run: |
./package-pypi-machxo2.sh
- name: Upload MachXO2 binary wheel artifact
uses: actions/upload-artifact@v3
with:
name: wheel
path: pypi-machxo2/dist/
- name: Test MachXO2 binary wheels
run: |
pip install pypi-machxo2/dist/*.whl
yowasp-xo2pll --help || true
yowasp-xo2bram --help
yowasp-xo2multi --help || true
yowasp-xo2pack --help || true
yowasp-xo2unpack --help || true
yowasp-nextpnr-machxo2 --help
yowasp-nextpnr-machxo2 --device LCMXO2-1200HC-4SG32C --test
- name: Build Nexus binary wheels
run: |
./package-pypi-nexus.sh
- name: Upload Nexus binary wheel artifact
./package-pypi-gowin.sh
- name: Upload Python artifact
uses: actions/upload-artifact@v3
with:
name: wheel
path: pypi-nexus/dist/
- name: Test Nexus binary wheels
name: dist-pypi
path: pypi-*/dist/
- name: Build JavaScript artifacts
run: |
pip install pypi-nexus/dist/*.whl
yowasp-prjoxide --help
yowasp-nextpnr-nexus --help
yowasp-nextpnr-nexus --device LIFCL-40-9BG400CES --test
- name: Build Gowin binary wheels
run: |
./package-pypi-gowin.sh
- name: Upload Gowin binary wheel artifact
./package-npmjs-ice40.sh
./package-npmjs-ecp5.sh
./package-npmjs-machxo2.sh
./package-npmjs-nexus.sh
- name: Upload JavaScript artifact
uses: actions/upload-artifact@v3
with:
name: wheel
path: pypi-gowin/dist/
- name: Test Gowin binary wheels
run: |
pip install pypi-gowin/dist/*.whl
yowasp-nextpnr-gowin --help
yowasp-nextpnr-gowin --device GW1N-LV1QN48C6/I5 --test
name: dist-npmjs
path: npmjs-*/dist/
- name: Print ccache statistics
run: |
ccache -s
publish:
test-python:
needs: build
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Download Python artifacts
uses: actions/download-artifact@v3
with:
name: dist-pypi
- name: Test iCE40 Python artifact
run: |
pip install pypi-ice40/dist/*.whl
yowasp-icepll -h || true
yowasp-icebram -h || true
yowasp-icemulti -h || true
yowasp-icepack -h || true
yowasp-iceunpack -h || true
yowasp-nextpnr-ice40 --help
yowasp-nextpnr-ice40 --hx8k --package ct256 --test
yowasp-nextpnr-ice40 --up5k --package sg48 --test
- name: Test ECP5 Python artifact
run: |
pip install pypi-ecp5/dist/*.whl
yowasp-ecppll --help || true
yowasp-ecpbram --help
yowasp-ecpmulti --help || true
yowasp-ecppack --help || true
yowasp-ecpunpack --help || true
yowasp-nextpnr-ecp5 --help
yowasp-nextpnr-ecp5 --um5g-25k --package CABGA381 --test
- name: Test MachXO2 Python artifact
run: |
pip install pypi-machxo2/dist/*.whl
yowasp-xo2pll --help || true
yowasp-xo2bram --help
yowasp-xo2multi --help || true
yowasp-xo2pack --help || true
yowasp-xo2unpack --help || true
yowasp-nextpnr-machxo2 --help
yowasp-nextpnr-machxo2 --device LCMXO2-1200HC-4SG32C --test
- name: Test Nexus Python artifact
run: |
pip install pypi-nexus/dist/*.whl
yowasp-prjoxide --help
yowasp-nextpnr-nexus --help
yowasp-nextpnr-nexus --device LIFCL-40-9BG400CES --test
- name: Test Gowin Python artifact
run: |
pip install pypi-gowin/dist/*.whl
yowasp-nextpnr-gowin --help
yowasp-nextpnr-gowin --device GW1N-LV1QN48C6/I5 --test
check: # group all `test (*)` workflows into one for the required status check
needs: [test-python]
if: always() && !contains(needs.*.result, 'cancelled')
runs-on: ubuntu-latest
steps:
- run: ${{ contains(needs.*.result, 'failure') && 'false' || 'true' }}
publish-python:
needs: build
runs-on: ubuntu-latest
environment: publish
permissions:
id-token: write
if: "!contains(github.event.head_commit.message, 'skip py')"
steps:
- uses: actions/download-artifact@v3
- name: Download Python artifacts
uses: actions/download-artifact@v3
with:
name: wheel
path: dist/
name: dist-pypi
path: dist-tree/
- name: Prepare artifacts for publishing
run: |
mkdir dist
find dist-tree -name '*.whl' -exec mv {} dist/ \;
- name: Publish wheels to Test PyPI
if: "github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop')"
uses: pypa/gh-action-pypi-publish@release/v1
Expand All @@ -137,6 +147,32 @@ jobs:
- name: Publish wheels to PyPI
if: "github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release')"
uses: pypa/gh-action-pypi-publish@release/v1
publish-javascript:
needs: check
runs-on: ubuntu-latest
environment: publish
permissions:
id-token: write
if: "!contains(github.event.head_commit.message, 'skip js')"
steps:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
- name: Download JavaScript artifacts
uses: actions/download-artifact@v3
with:
name: dist-npmjs
path: dist/
- name: Publish package to NPM (dry run)
if: "github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop')"
run: for pkg in $(find dist -name '*.tgz'); do npm publish --access public file:$pkg --dry-run; done
- name: Publish package to NPM
if: "github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/release')"
run: for pkg in $(find dist -name '*.tgz'); do npm publish --access public file:$pkg; done
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
release:
needs: build
runs-on: ubuntu-latest
Expand Down
6 changes: 3 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)

PYTHON=$(which ${PYTHON:-python})

WASI_SDK=wasi-sdk-19.0
WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz
WASI_SDK=wasi-sdk-20.0
WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz
if ! [ -d ${WASI_SDK} ]; then curl -L ${WASI_SDK_URL} | tar xzf -; fi
WASI_SDK_PATH=$(pwd)/${WASI_SDK}

Expand All @@ -17,7 +17,7 @@ EIGEN=eigen-3.4.0
EIGEN_URL=https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
if ! [ -d ${EIGEN} ]; then curl -L ${EIGEN_URL} | tar xzf -; fi

# Threading requires pre-release wasi-sdk
# Threading is currently experimental.
WASI_TARGET="wasm32-wasi"
WASI_SYSROOT="--sysroot ${WASI_SDK_PATH}/share/wasi-sysroot"
WASI_CFLAGS="-flto"
Expand Down
9 changes: 9 additions & 0 deletions npmjs-common/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/package-lock.json
/package.json
/node_modules
/dist

/*.wasm
/gen
/share
/index.*
41 changes: 41 additions & 0 deletions npmjs-common/package-in.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@yowasp/nextpnr-__ARCH__",
"version": "__VERSION__",
"description": "nextpnr-__ARCH__ FPGA place and route tool",
"author": "Catherine <[email protected]>",
"license": "ISC",
"homepage": "https://yowasp.org/",
"repository": {
"type": "git",
"url": "git+https://github.com/YoWASP/nextpnr.git"
},
"bugs": {
"url": "https://github.com/YoWASP/nextpnr/issues"
},
"type": "module",
"files": [
"lib/api.d.ts",
"gen/bundle-*.js",
"gen/resources-*.js",
"gen/*.wasm",
"gen/share/"
],
"exports": {
"node": "./gen/bundle-node.js",
"browser": "./gen/bundle-browser.js",
"types": "./lib/api.d.ts"
},
"types": "./lib/api.d.ts",
"devDependencies": {
"@bytecodealliance/jco": "^0.14.1",
"@yowasp/runtime": "5.0.28",
"esbuild": "^0.19.8"
},
"scripts": {
"pack": "yowasp-pack-resources gen/resources-nextpnr-__ARCH__.js gen share",
"transpile": "jco new __FILENAME__ --wasi-command --output __BASENAME__ && jco transpile __BASENAME__ --instantiation async --no-typescript --no-namespaced-exports --map 'wasi:io/*=runtime#io' --map 'wasi:cli/*=runtime#cli' --map 'wasi:clocks/*=runtime#*' --map 'wasi:filesystem/*=runtime#fs' --map 'wasi:random/*=runtime#random' --out-dir gen/",
"build:node": "esbuild --bundle lib/api.js --outfile=gen/bundle-node.js --format=esm --platform=node",
"build:browser": "esbuild --bundle lib/api.js --outfile=gen/bundle-browser.js --format=esm --platform=browser",
"all": "npm run transpile && npm run pack && npm run build:node && npm run build:browser"
}
}
48 changes: 48 additions & 0 deletions npmjs-common/prepare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import os
import re
import sys
import json
import subprocess


arch = sys.argv[1]


nextpnr_version_raw = subprocess.check_output([
"git", "-C", "../nextpnr-src", "describe", "--tags", "HEAD"
], encoding="utf-8").strip()

git_rev_list_raw = subprocess.check_output([
"git", "rev-list", "HEAD"
], encoding="utf-8").split()

nextpnr_version = re.match(r"^nextpnr-(\d+).(\d+)(?:-(\d+)-)?", nextpnr_version_raw)
nextpnr_major = int(nextpnr_version[1])
nextpnr_minor = int(nextpnr_version[2])
nextpnr_node = int(nextpnr_version[3] or "0")

distance = len(git_rev_list_raw) - 1

if os.environ.get("RELEASE_BRANCH", "false") in ("true", "1", "yes"):
version = f"{nextpnr_major}.{nextpnr_minor}.{distance}"
else:
version = f"{nextpnr_major}.{nextpnr_minor + 1}.{nextpnr_node}-dev.{distance}"
print(f"version {version}")


with open("package-local.json", "rt") as f:
package_local = json.load(f)
with open("package-in.json", "rt") as f:
package_json = json.load(f)
package_json["version"] = version
package_json["name"] = package_json["name"].replace("__ARCH__", arch)
package_json["description"] = package_json["description"].replace("__ARCH__", arch)
package_json["scripts"]["pack"] = package_json["scripts"]["pack"].replace("__ARCH__", arch)
transpile_commands = []
for transpile_file in package_local["scripts"]["transpile"]:
transpile_commands.append(package_json["scripts"]["transpile"]
.replace("__FILENAME__", transpile_file)
.replace("__BASENAME__", os.path.basename(transpile_file)))
package_json["scripts"]["transpile"] = " && ".join(transpile_commands)
with open("package.json", "wt") as f:
json.dump(package_json, f, indent=2)
9 changes: 9 additions & 0 deletions npmjs-ecp5/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/package-lock.json
/package.json
/node_modules
/dist

/*.wasm
/gen
/share
/index.*
30 changes: 30 additions & 0 deletions npmjs-ecp5/lib/api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export type Tree = {
[name: string]: Tree | string | Uint8Array
};

export class Exit extends Error {
code: number;
files: Tree;
}

export type Command = (args?: string[], files?: Tree, options?: {
printLine?: (line: string) => void,
decodeASCII?: boolean
}) => Promise<Tree>;


export const runEcppll: Command;
export const runEcpbram: Command;
export const runEcpmulti: Command;
export const runEcppack: Command;
export const runEcpunpack: Command;
export const runNextpnrEcp5: Command;

export const commands: {
'ecppll': Command,
'ecpbram': Command,
'ecpmulti': Command,
'ecppack': Command,
'ecpunpack': Command,
'nextpnr-ecp5': Command,
};
Loading

0 comments on commit d39139e

Please sign in to comment.