diff --git a/.github/workflows/js-sdk-release.yml b/.github/workflows/js-sdk-release.yml new file mode 100644 index 00000000..d0caad5d --- /dev/null +++ b/.github/workflows/js-sdk-release.yml @@ -0,0 +1,111 @@ +# SPDX-FileCopyrightText: © 2025 Phala Network +# +# SPDX-License-Identifier: Apache-2.0 + +name: Publish JS SDK to npm +on: + push: + tags: ['js-sdk-v*'] + workflow_dispatch: + inputs: + npm_tag: + description: 'npm dist-tag (latest, beta, canary)' + required: true + default: 'latest' + type: choice + options: + - latest + - beta + - canary + +permissions: + id-token: write + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Upgrade npm for OIDC support + run: | + npm install -g npm@latest + echo "npm version: $(npm --version)" + + - name: Verify OIDC token availability + run: | + if [ -n "${ACTIONS_ID_TOKEN_REQUEST_URL}" ] && [ -n "${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" ]; then + echo "OIDC token available" + else + echo "OIDC token NOT available" + echo "Check workflow permissions include 'id-token: write'" + exit 1 + fi + + - name: Verify repository configuration + working-directory: sdk/js + run: | + echo "Checking repository consistency..." + GIT_REPO=$(git remote get-url origin | sed 's/.*github.com[/:]//; s/.git$//') + PKG_REPO=$(node -e "console.log(require('./package.json').repository?.url || '')" | sed 's|https://github.com/||; s|git+||; s|.git$||') + echo "Git remote: $GIT_REPO" + echo "package.json: $PKG_REPO" + if [ "$GIT_REPO" != "$PKG_REPO" ]; then + echo "Repository mismatch!" + echo "This will cause 422 error during publish" + exit 1 + fi + echo "Repositories match" + + - name: Install dependencies + working-directory: sdk/js + run: npm install + + - name: Build + working-directory: sdk/js + run: npm run build + + - name: Determine npm dist-tag + id: tag + run: | + VERSION="${GITHUB_REF_NAME#js-sdk-v}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "tag=${{ github.event.inputs.npm_tag }}" >> "$GITHUB_OUTPUT" + else + # auto-detect from git tag: js-sdk-v0.5.8-beta.1 -> beta + if echo "$VERSION" | grep -qiE '(beta|alpha|rc|preview)'; then + echo "tag=beta" >> "$GITHUB_OUTPUT" + else + echo "tag=latest" >> "$GITHUB_OUTPUT" + fi + fi + + - name: Publish to npm + working-directory: sdk/js + run: | + NPM_TAG="${{ steps.tag.outputs.tag }}" + echo "Publishing with dist-tag: $NPM_TAG" + npm publish --access public --provenance --tag "$NPM_TAG" + + - name: GitHub Release + if: github.event_name == 'push' + uses: softprops/action-gh-release@v1 + with: + name: "JS SDK v${{ steps.tag.outputs.version }}" + body: | + ## npm Package + + **Package**: `@phala/dstack-sdk@${{ steps.tag.outputs.version }}` + + **Install**: `npm install @phala/dstack-sdk@${{ steps.tag.outputs.version }}` + + **Dist-tag**: `${{ steps.tag.outputs.tag }}` + + **Registry**: https://www.npmjs.com/package/@phala/dstack-sdk/v/${{ steps.tag.outputs.version }} diff --git a/.github/workflows/python-sdk-release.yml b/.github/workflows/python-sdk-release.yml new file mode 100644 index 00000000..692bcdd6 --- /dev/null +++ b/.github/workflows/python-sdk-release.yml @@ -0,0 +1,70 @@ +# SPDX-FileCopyrightText: © 2025 Phala Network +# +# SPDX-License-Identifier: Apache-2.0 + +name: Publish Python SDK to PyPI +on: + push: + tags: ['python-sdk-v*'] + workflow_dispatch: + inputs: + target: + description: 'Publish target' + required: true + default: 'pypi' + type: choice + options: + - pypi + - testpypi + +permissions: + id-token: write + contents: write + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install PDM + run: pip install pdm + + - name: Build distribution + working-directory: sdk/python + run: pdm build + + - name: Parse version + id: version + run: echo "version=${GITHUB_REF_NAME#python-sdk-v}" >> "$GITHUB_OUTPUT" + + - name: Publish to PyPI + if: github.event_name == 'push' || github.event.inputs.target == 'pypi' + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: sdk/python/dist + + - name: Publish to TestPyPI + if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi' + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + packages-dir: sdk/python/dist + + - name: GitHub Release + if: github.event_name == 'push' + uses: softprops/action-gh-release@v1 + with: + name: "Python SDK v${{ steps.version.outputs.version }}" + body: | + ## PyPI Package + + **Package**: `dstack-sdk ${{ steps.version.outputs.version }}` + + **Install**: `pip install dstack-sdk==${{ steps.version.outputs.version }}` + + **Registry**: https://pypi.org/project/dstack-sdk/${{ steps.version.outputs.version }}/ diff --git a/sdk/js/.claude/settings.local.json b/sdk/js/.claude/settings.local.json new file mode 100644 index 00000000..ae4e8b80 --- /dev/null +++ b/sdk/js/.claude/settings.local.json @@ -0,0 +1,20 @@ +{ + "permissions": { + "allow": [ + "Bash(npm run clean:*)", + "Bash(npm run build:*)", + "Bash(npm test)", + "Bash(export DSTACK_SIMULATOR_ENDPOINT=/Users/leechael/workshop/phala/dstack/sdk/simulator/dstack.sock)", + "Bash(export TAPPD_SIMULATOR_ENDPOINT=/Users/leechael/workshop/phala/dstack/sdk/simulator/tappd.sock)", + "Bash(node:*)", + "Bash(rm:*)", + "Bash(npm run test:ci:*)", + "Bash(grep:*)", + "Bash(npm test:*)", + "Bash(npm install)", + "Bash(npm run test:*)", + "Bash(npx tsc:*)" + ], + "deny": [] + } +} diff --git a/sdk/js/.claude/settings.local.json.license b/sdk/js/.claude/settings.local.json.license new file mode 100644 index 00000000..84ac4efa --- /dev/null +++ b/sdk/js/.claude/settings.local.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: © 2025 Phala Network + +SPDX-License-Identifier: Apache-2.0 diff --git a/sdk/js/package.json b/sdk/js/package.json index 01946b89..cfc8d8c4 100644 --- a/sdk/js/package.json +++ b/sdk/js/package.json @@ -1,6 +1,6 @@ { "name": "@phala/dstack-sdk", - "version": "0.5.7", + "version": "0.5.8-beta.0", "description": "dstack SDK", "main": "dist/node/index.js", "types": "dist/node/index.d.ts", @@ -92,6 +92,11 @@ "dstack", "Phala" ], + "repository": { + "type": "git", + "url": "https://github.com/Dstack-TEE/dstack", + "directory": "sdk/js" + }, "author": "Leechael Yim", "license": "Apache-2.0", "dependencies": { @@ -99,7 +104,7 @@ }, "devDependencies": { "@types/node": "latest", - "typescript": "latest", + "typescript": "^5.7.0", "vitest": "^3.2.4" }, "optionalDependencies": { diff --git a/sdk/js/src/encrypt-env-vars.ts b/sdk/js/src/encrypt-env-vars.ts index 6fc45378..cef27b9f 100644 --- a/sdk/js/src/encrypt-env-vars.ts +++ b/sdk/js/src/encrypt-env-vars.ts @@ -40,7 +40,7 @@ export async function encryptEnvVars(envs: EnvVar[], publicKeyHex: string) { // Import shared key for AES-GCM const importedShared = await crypto.subtle.importKey( "raw", - shared, + new Uint8Array(shared), { name: "AES-GCM", length: 256 }, true, ["encrypt"], @@ -64,4 +64,4 @@ export async function encryptEnvVars(envs: EnvVar[], publicKeyHex: string) { result.set(new Uint8Array(encrypted), publicKey.length + iv.length); return uint8ArrayToHex(result); -} \ No newline at end of file +} diff --git a/sdk/js/tsconfig.browser.json b/sdk/js/tsconfig.browser.json index a790e4b3..cd759b2d 100644 --- a/sdk/js/tsconfig.browser.json +++ b/sdk/js/tsconfig.browser.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "target": "es2018", + "target": "es2020", "module": "es2015", "lib": ["es2018", "dom"], "outDir": "./dist/browser", @@ -11,8 +11,8 @@ }, "include": [ "src/encrypt-env-vars.browser.ts", - "src/get-compose-hash.browser.ts", + "src/get-compose-hash.browser.ts", "src/verify-env-encrypt-public-key.browser.ts" ], "exclude": ["node_modules", "**/*.test.ts"] -} \ No newline at end of file +} diff --git a/sdk/js/tsconfig.json b/sdk/js/tsconfig.json index d63ebfd9..1a77147b 100644 --- a/sdk/js/tsconfig.json +++ b/sdk/js/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2018", + "target": "es2020", "module": "commonjs", "lib": ["es2018"], "declaration": true, diff --git a/sdk/js/tsconfig.node.json b/sdk/js/tsconfig.node.json index 2814865e..a8004eeb 100644 --- a/sdk/js/tsconfig.node.json +++ b/sdk/js/tsconfig.node.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "target": "es2018", + "target": "es2020", "module": "commonjs", "lib": ["es2018"], "outDir": "./dist/node", @@ -11,4 +11,4 @@ }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.test.ts", "src/*.browser.ts"] -} \ No newline at end of file +} diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index e0ba5d33..f0ee1310 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -4,7 +4,7 @@ [project] name = "dstack-sdk" -version = "0.5.3" +version = "0.5.4b0" description = "dstack SDK for Python" authors = [ {name = "Leechael Yim", email = "yanleech@gmail.com"}, @@ -103,7 +103,7 @@ repository = "pypi" fmt = {composite = ["ruff format src/ tests/", "ruff check --fix src/ tests/"]} format = {composite = ["ruff format src/ tests/", "ruff check --fix src/ tests/"]} -# Linting scripts +# Linting scripts lint = {composite = ["ruff check src/ tests/", "mypy src/"]} check = {composite = ["ruff check src/ tests/", "ruff format --check src/ tests/", "mypy src/"]} @@ -134,4 +134,4 @@ solana = [ ] ethereum = [ "web3", -] \ No newline at end of file +]