main
yml 200 lines 6.64 KB
Raw
1 name: "smbCloud Deploy"
2 description: "Install the smbCloud CLI (smb) and deploy an app non-interactively from CI."
3 author: "smbCloud (Splitfire AB)"
4
5 branding:
6 icon: "upload-cloud"
7 color: "blue"
8
9 inputs:
10 token:
11 description: >-
12 smbCloud auth token contents. Provision it once (see docs/ci.md in
13 smbcloud-cli) and pass it from a CI secret. Written to the CLI state dir
14 so `smb` is authenticated without an interactive `smb login`.
15 required: true
16 environment:
17 description: "smbCloud environment: production or dev."
18 required: false
19 default: "production"
20 project:
21 description: >-
22 Sub-project name to deploy for monorepo configs with [[projects]] entries.
23 Matches the `name` field in .smb/config.toml. Omit for single-project configs.
24 required: false
25 default: ""
26 working-directory:
27 description: "Directory containing .smb/config.toml. Defaults to the repo root."
28 required: false
29 default: "."
30 version:
31 description: >-
32 smbCloud CLI version to install (e.g. 0.5.0 or v0.5.0). Use 'latest' for
33 the most recent GitHub release.
34 required: false
35 default: "latest"
36 ssh-private-key:
37 description: >-
38 Optional SSH private key contents for rsync/SSH deploy paths. Installed at
39 ~/.ssh/<ssh-key-name>.
40 required: false
41 default: ""
42 ssh-key-name:
43 description: >-
44 Filename for the installed SSH private key under ~/.ssh. smbCloud rsync
45 deploys expect the account-scoped name `id_<user-id>@smbcloud`. Required
46 when ssh-private-key is set.
47 required: false
48 default: ""
49 ssh-known-hosts:
50 description: >-
51 Optional known_hosts entries appended to ~/.ssh/known_hosts. Recommended
52 for SSH deploys instead of disabling host-key checking.
53 required: false
54 default: ""
55 args:
56 description: "Extra arguments appended to the `smb deploy` invocation."
57 required: false
58 default: ""
59 cli-repository:
60 description: "GitHub repository to download the CLI binary from."
61 required: false
62 default: "smbcloudXYZ/smbcloud-cli"
63
64 outputs:
65 smb-path:
66 description: "Absolute path to the installed smb binary."
67 value: ${{ steps.install.outputs.smb-path }}
68 version:
69 description: "Resolved CLI version that was installed."
70 value: ${{ steps.install.outputs.version }}
71
72 runs:
73 using: "composite"
74 steps:
75 - name: Install smbCloud CLI
76 id: install
77 shell: bash
78 env:
79 INPUT_VERSION: ${{ inputs.version }}
80 INPUT_CLI_REPOSITORY: ${{ inputs.cli-repository }}
81 run: |
82 set -euo pipefail
83
84 case "$(uname -s)" in
85 Linux) os="linux" ;;
86 Darwin) os="macos" ;;
87 MINGW*|MSYS*|CYGWIN*) os="win" ;;
88 *) echo "::error::Unsupported OS: $(uname -s)"; exit 1 ;;
89 esac
90
91 case "$(uname -m)" in
92 x86_64|amd64) arch="amd64" ;;
93 arm64|aarch64) arch="arm64" ;;
94 *) echo "::error::Unsupported architecture: $(uname -m)"; exit 1 ;;
95 esac
96
97 asset="smb-${os}-${arch}"
98 bin_name="smb"
99 if [ "$os" = "win" ]; then
100 asset="${asset}.exe"
101 bin_name="smb.exe"
102 fi
103
104 if [ "${INPUT_VERSION}" = "latest" ]; then
105 url="https://github.com/${INPUT_CLI_REPOSITORY}/releases/latest/download/${asset}"
106 else
107 tag="${INPUT_VERSION#v}"
108 url="https://github.com/${INPUT_CLI_REPOSITORY}/releases/download/v${tag}/${asset}"
109 fi
110
111 install_dir="${RUNNER_TEMP:-/tmp}/smbcloud-cli-bin"
112 mkdir -p "$install_dir"
113 smb_path="${install_dir}/${bin_name}"
114
115 echo "Downloading ${asset} from ${url}"
116 curl --fail --location --retry 3 --retry-delay 2 --proto '=https' --tlsv1.2 \
117 --output "$smb_path" "$url"
118 chmod +x "$smb_path"
119
120 echo "$install_dir" >> "$GITHUB_PATH"
121 echo "smb-path=${smb_path}" >> "$GITHUB_OUTPUT"
122
123 resolved_version="$("$smb_path" --version 2>/dev/null | awk '{print $NF}' || echo "${INPUT_VERSION}")"
124 echo "version=${resolved_version}" >> "$GITHUB_OUTPUT"
125 echo "Installed smb ${resolved_version} at ${smb_path}"
126
127 - name: Configure smbCloud credentials
128 shell: bash
129 env:
130 INPUT_TOKEN: ${{ inputs.token }}
131 INPUT_ENVIRONMENT: ${{ inputs.environment }}
132 INPUT_SSH_PRIVATE_KEY: ${{ inputs.ssh-private-key }}
133 INPUT_SSH_KEY_NAME: ${{ inputs.ssh-key-name }}
134 INPUT_SSH_KNOWN_HOSTS: ${{ inputs.ssh-known-hosts }}
135 run: |
136 set -euo pipefail
137
138 if [ -z "${INPUT_TOKEN}" ]; then
139 echo "::error::'token' input is required."
140 exit 1
141 fi
142
143 case "${INPUT_ENVIRONMENT}" in
144 production) smb_dir=".smb" ;;
145 dev) smb_dir=".smb-dev" ;;
146 *) echo "::error::Invalid environment '${INPUT_ENVIRONMENT}' (use 'production' or 'dev')."; exit 1 ;;
147 esac
148
149 state_dir="${HOME}/${smb_dir}"
150 mkdir -p "$state_dir"
151 umask 077
152 printf '%s' "${INPUT_TOKEN}" > "${state_dir}/token"
153 chmod 600 "${state_dir}/token"
154 echo "Wrote auth token to ${state_dir}/token"
155
156 if [ -n "${INPUT_SSH_PRIVATE_KEY}" ]; then
157 if [ -z "${INPUT_SSH_KEY_NAME}" ]; then
158 echo "::error::'ssh-key-name' is required when 'ssh-private-key' is set."
159 exit 1
160 fi
161 ssh_dir="${HOME}/.ssh"
162 mkdir -p "$ssh_dir"
163 chmod 700 "$ssh_dir"
164 key_path="${ssh_dir}/${INPUT_SSH_KEY_NAME}"
165 printf '%s\n' "${INPUT_SSH_PRIVATE_KEY}" > "$key_path"
166 chmod 600 "$key_path"
167 echo "Installed SSH key at ${key_path}"
168
169 if [ -n "${INPUT_SSH_KNOWN_HOSTS}" ]; then
170 printf '%s\n' "${INPUT_SSH_KNOWN_HOSTS}" >> "${ssh_dir}/known_hosts"
171 chmod 600 "${ssh_dir}/known_hosts"
172 echo "Appended entries to ${ssh_dir}/known_hosts"
173 fi
174 fi
175
176 - name: Deploy
177 shell: bash
178 working-directory: ${{ inputs.working-directory }}
179 env:
180 # The CLI's --ci flag binds env SMB_CI and parses it as a strict bool,
181 # so this must be "true"/"false", not "1". We also pass --ci explicitly.
182 SMB_CI: "true"
183 INPUT_ENVIRONMENT: ${{ inputs.environment }}
184 INPUT_PROJECT: ${{ inputs.project }}
185 INPUT_ARGS: ${{ inputs.args }}
186 run: |
187 set -euo pipefail
188
189 cmd=(smb --ci --environment "${INPUT_ENVIRONMENT}" deploy)
190 if [ -n "${INPUT_PROJECT}" ]; then
191 cmd+=(--project "${INPUT_PROJECT}")
192 fi
193 if [ -n "${INPUT_ARGS}" ]; then
194 # shellcheck disable=SC2206
195 extra=(${INPUT_ARGS})
196 cmd+=("${extra[@]}")
197 fi
198
199 echo "Running: ${cmd[*]}"
200 "${cmd[@]}"