1 name: NPM Release
2
3 on:
4 push:
5 tags:
6 - "v*.*.*"
7 workflow_dispatch:
8
9 permissions:
10 id-token: write
11 contents: read
12
13 env:
14 SMB_CLIENT_ID: ${{ secrets.SMB_CLIENT_ID }}
15 SMB_CLIENT_SECRET: ${{ secrets.SMB_CLIENT_SECRET }}
16 SMB_API_HOST: ${{ secrets.SMB_API_HOST }}
17 SMB_API_PROTOCOL: ${{ secrets.SMB_API_PROTOCOL }}
18 GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
19 GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
20 GH_OAUTH_REDIRECT_HOST: ${{ secrets.GH_OAUTH_REDIRECT_HOST }}
21 GH_OAUTH_REDIRECT_PORT: ${{ secrets.GH_OAUTH_REDIRECT_PORT }}
22
23 jobs:
24 publish-npm-binaries:
25 name: Publish NPM packages
26 runs-on: ${{ matrix.build.OS }}
27 strategy:
28 fail-fast: false
29 matrix:
30 build:
31 - {
32 NAME: linux-x64-glibc,
33 OS: ubuntu-latest,
34 TARGET: x86_64-unknown-linux-gnu,
35 }
36 # Cannot cross-compile for now
37 #- {
38 # NAME: linux-arm64-glibc,
39 # OS: ubuntu-latest,
40 # TOOLCHAIN: stable,
41 # TARGET: aarch64-unknown-linux-gnu,
42 # }
43 - {
44 NAME: win32-x64-msvc,
45 OS: windows-2022,
46 TARGET: x86_64-pc-windows-msvc,
47 }
48 - {
49 NAME: win32-arm64-msvc,
50 OS: windows-2022,
51 TARGET: aarch64-pc-windows-msvc,
52 }
53 - {
54 NAME: darwin-x64,
55 OS: macos-15-intel,
56 TARGET: x86_64-apple-darwin,
57 }
58 - {
59 NAME: darwin-arm64,
60 OS: macos-latest,
61 TARGET: aarch64-apple-darwin,
62 }
63 steps:
64 - name: Checkout
65 uses: actions/checkout@v6
66
67 - name: Set the release version
68 shell: bash
69 run: |
70 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
71 release_version="${GITHUB_REF_NAME#v}"
72 else
73 release_version="$(sed -n 's/^version = "\(.*\)"/\1/p' crates/cli/Cargo.toml | head -n 1)"
74 fi
75
76 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
77
78 - name: Read Rust toolchain
79 shell: bash
80 run: |
81 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
82 if [ -z "$rust_toolchain" ]; then
83 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
84 exit 1
85 fi
86
87 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
88
89 - name: Install toolkit
90 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
91 with:
92 toolchain: ${{ env.RUST_TOOLCHAIN }}
93
94 - name: Install Rust target
95 shell: bash
96 run: |
97 rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
98 rustup target list --installed
99
100 - name: Create .env file
101 run: |
102 touch .env
103 echo CLI_CLIENT_SECRET=${{ secrets.CLI_CLIENT_SECRET }} >> .env
104 cat .env
105
106 - name: Build
107 env:
108 GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
109 GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
110 GH_OAUTH_REDIRECT_URI: ${{ secrets.GH_OAUTH_REDIRECT_URI }}
111 shell: bash
112 run: |
113 cargo build --release --locked --target ${{ matrix.build.TARGET }}
114
115 - name: Install node
116 uses: actions/setup-node@v6
117 with:
118 node-version-file: .nvmrc
119 registry-url: "https://registry.npmjs.org"
120
121 - name: Publish to NPM
122 shell: bash
123 run: |
124 # We want to name our npm package @smbcloud/cli, but the main command is smb.
125 # This is the tricky part. All the optional dependencies should follow the naming convention.
126 # So, we will generate @smbcloud/cli-${matrix.build.TARGET}
127
128 # Move to the npm directory
129 cd npm
130 # set the binary name, this is from the rust Cargo.toml file
131 cargo_bin="smb"
132 node_pkg_prefix="cli"
133 # derive the OS and architecture from the build matrix name
134 # note: when split by a hyphen, first part is the OS and the second is the architecture
135 node_os=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f1)
136 export node_os
137 node_arch=$(echo "${{ matrix.build.NAME }}" | cut -d '-' -f2)
138 export node_arch
139 # set the version
140 export node_version="${{ env.RELEASE_VERSION }}"
141 # set the package name
142 # note: use 'windows' as OS name instead of 'win32'
143 if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
144 export node_pkg="${node_pkg_prefix}-windows-${node_arch}"
145 else
146 export node_pkg="${node_pkg_prefix}-${node_os}-${node_arch}"
147 fi
148 # create the package directory
149 mkdir -p "${node_pkg}/bin"
150 # generate package metadata
151 node ./scripts/render-platform-package.cjs "${node_pkg}" "${node_version}" "${node_os}" "${node_arch}"
152 # copy the binary into the package
153 # note: windows binaries has '.exe' extension
154 if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then
155 cargo_bin="${cargo_bin}.exe"
156 fi
157 cp "../target/${{ matrix.build.TARGET }}/release/${cargo_bin}" "${node_pkg}/bin"
158 # publish the package
159 cd "${node_pkg}"
160 npm_package_name="@smbcloud/${node_pkg}"
161 if npm view "${npm_package_name}@${node_version}" version >/dev/null 2>&1; then
162 echo "${npm_package_name}@${node_version} already exists on npm, skipping publish"
163 exit 0
164 fi
165 npm publish --access public
166
167 publish-npm-base:
168 name: Publish the base NPM package
169 needs: publish-npm-binaries
170 runs-on: ubuntu-latest
171 steps:
172 - name: Checkout
173 uses: actions/checkout@v6
174
175 - name: Set the release version
176 shell: bash
177 run: |
178 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
179 release_version="${GITHUB_REF_NAME#v}"
180 else
181 release_version="$(sed -n 's/^version = "\(.*\)"/\1/p' crates/cli/Cargo.toml | head -n 1)"
182 fi
183
184 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
185
186 - name: Install node
187 uses: actions/setup-node@v6
188 with:
189 node-version-file: .nvmrc
190 registry-url: "https://registry.npmjs.org"
191
192 - name: Publish the package
193 shell: bash
194 run: |
195 cd npm/smbcloud-cli
196
197 node ../scripts/render-main-package.cjs "./package.json" "${{ env.RELEASE_VERSION }}"
198
199 npm_package_name="@smbcloud/cli"
200 npm_package_version="${{ env.RELEASE_VERSION }}"
201 if npm view "${npm_package_name}@${npm_package_version}" version >/dev/null 2>&1; then
202 echo "${npm_package_name}@${npm_package_version} already exists on npm, skipping publish"
203 exit 0
204 fi
205
206 npm install
207 npm run build
208 npm publish --access public