Skip to content
Merged
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
26 changes: 4 additions & 22 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,12 @@ jobs:
echo "formula_path=${FORMULA_PATH}"
} >> "$GITHUB_OUTPUT"

- name: Open pull request on Homebrew tap
- name: Commit Homebrew formula update
working-directory: homebrew-tap
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
EXECUTABLE_NAME: ${{ steps.tap.outputs.executable }}
FORMULA_PATH: ${{ steps.tap.outputs.formula_path }}
SOURCE_REPO: ${{ github.repository }}
SERVER_URL: ${{ github.server_url }}
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
run: |
set -euo pipefail

Expand All @@ -243,27 +240,12 @@ jobs:
exit 0
fi

BASE_BRANCH="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')"
BRANCH="release/${EXECUTABLE_NAME}-${RELEASE_TAG}"

git config user.name "appwrite-bot[bot]"
git config user.email "217594562+appwrite-bot[bot]@users.noreply.github.com"

git checkout -B "$BRANCH"
git add "$FORMULA_PATH"
git commit -m "${EXECUTABLE_NAME} ${RELEASE_TAG}"
git push -f -u origin "$BRANCH"

PR_TITLE="${EXECUTABLE_NAME} ${RELEASE_TAG}"
PR_BODY=$(printf 'Automated formula update for the `%s` CLI release [`%s`](%s/%s/releases/tag/%s).\n\nOpened automatically by the `%s` publish workflow after release binaries were uploaded.' "$EXECUTABLE_NAME" "$RELEASE_TAG" "$SERVER_URL" "$SOURCE_REPO" "$RELEASE_TAG" "${SOURCE_REPO#*/}")

EXISTING_PR="$(gh pr list --head "$BRANCH" --state open --json number --jq '.[0].number' || true)"
if [ -n "$EXISTING_PR" ]; then
gh pr edit "$EXISTING_PR" --title "$PR_TITLE" --body "$PR_BODY"
else
gh pr create \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--base "$BASE_BRANCH" \
--head "$BRANCH"
fi
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
git pull --rebase origin "$BRANCH"
git push origin "HEAD:${BRANCH}"
Comment thread
ChiragAgg5k marked this conversation as resolved.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 24.0.0

* Added: `login` against Cloud now signs in through your browser
* Updated: `--email`, `--password`, `--mfa`, and `--code` now apply to self-hosted instances only
* Updated: Existing Cloud sessions keep working in read-only mode until you run `login` again

## 23.2.0

* Added: `apps` installation commands: `list-installations`, `get-installation`, `delete-installation`, `create-installation-token`
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using

```sh
$ appwrite -v
23.2.0
24.0.0
```

### Install using prebuilt binaries
Expand Down Expand Up @@ -83,7 +83,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
Once the installation completes, you can verify your install using
```
$ appwrite -v
23.2.0
24.0.0
```

## Getting Started
Expand Down
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
# You can use "View source" of this page to see the full script.

# REPO
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/23.2.0/appwrite-cli-win-x64.exe"
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/23.2.0/appwrite-cli-win-arm64.exe"
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/24.0.0/appwrite-cli-win-x64.exe"
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/24.0.0/appwrite-cli-win-arm64.exe"

$APPWRITE_BINARY_NAME = "appwrite.exe"

Expand Down
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ verifyMacOSCodeSignature() {
downloadBinary() {
echo "[2/5] Downloading executable for $OS ($ARCH) ..."

GITHUB_LATEST_VERSION="23.2.0"
GITHUB_LATEST_VERSION="24.0.0"
GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"

Expand Down
12 changes: 8 additions & 4 deletions lib/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
isRegionalCloudEndpoint,
openBrowser,
} from "../utils.js";
import { isFlagEnabled } from "../flags.js";
import ID from "../id.js";
import {
questionsListFactors,
Expand Down Expand Up @@ -476,8 +475,13 @@ export const loginCommand = async ({
const configEndpoint = normalizeCloudConsoleEndpoint(
(endpoint ?? globalConfig.getEndpoint()) || DEFAULT_ENDPOINT,
);
const shouldUseCloudLogin =
isFlagEnabled("oauthLogin") && isCloudLoginEndpoint(configEndpoint);
const shouldUseCloudLogin = isCloudLoginEndpoint(configEndpoint);

if (shouldUseCloudLogin && (email || password || mfa || code)) {
throw new Error(
`Cloud sign-in happens in your browser. Run '${EXECUTABLE_NAME} login' without --email, --password, --mfa or --code — those options are for self-hosted instances.`,
);
}

let oldCurrent = globalConfig.getCurrentSession();

Expand All @@ -493,7 +497,7 @@ export const loginCommand = async ({

if (account) {
if (
isFlagEnabled("oauthLogin") &&
shouldUseCloudLogin &&
!globalConfig.getAccessToken() &&
globalConfig.getCookie()
) {
Expand Down
8 changes: 4 additions & 4 deletions lib/commands/generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ export const register = new Command("register")

export const login = new Command("login")
.description(commandDescriptions["login"])
.option(`--email [email]`, `Email`)
.option(`--password [password]`, `Password`)
.option(`--email [email]`, `Email, for self hosted instances`)
.option(`--password [password]`, `Password, for self hosted instances`)
.option(
`--mfa [factor]`,
`Factor used for MFA. Must be one of: email, phone, totp, recoveryCode`,
`Factor used for MFA on self hosted instances. Must be one of: email, phone, totp, recoveryCode`,
)
.option(`--code [code]`, `Code used for MFA`)
.option(`--code [code]`, `Code used for MFA on self hosted instances`)
.option(
`--endpoint [endpoint]`,
`Appwrite endpoint for self hosted instances`,
Expand Down
6 changes: 3 additions & 3 deletions lib/commands/services/backups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,17 @@ const backupsCreateRestorationCommand = backups
.command(`create-restoration`)
.description(`Create and trigger a new restoration for a backup on a project.

For a backup of one database, the restoration resolves its destination before it is queued. Pass \`newResourceId\` to restore into that database ID, including the archived database ID to overwrite it. When \`newResourceId\` is omitted, a new database ID is generated and returned in \`options\`.
For a backup of one database, the restoration resolves its destination before it is queued. When \`newResourceId\` is omitted, the archived database is restored in place and its own ID is returned in \`options\`. Pass a different \`newResourceId\` to restore alongside it as a new database instead.

The restoration migration records the archived database in \`resourceId\` and \`resourceType\`, and the resolved database in \`destinationResourceId\` and \`destinationResourceType\`. Database types are stored canonically as \`database\`, \`documentsdb\`, or \`vectorsdb\`. Project-wide restorations leave these fields empty because they do not have a single source or destination database.

To list every migration related to one database, use its canonical type in a nested \`OR(AND(...), AND(...), AND(...))\` across the root, parent, and destination relation pairs: \`(resourceType, resourceId)\`, \`(parentResourceType, parentResourceId)\`, and \`(destinationResourceType, destinationResourceId)\`. Legacy and TablesDB databases use \`database\`; the operational \`resourceType\` of a table migration is not rewritten to \`tablesdb\`.

When restoring a DocumentsDB or VectorsDB database to a new resource from a dedicated source, the restore provisions a fresh dedicated backing database at the source database's own specification.
When restoring a DocumentsDB or VectorsDB database from a dedicated source, the restore provisions a fresh dedicated backing database at the source database's own specification and lands the data there. An in-place restore swaps the database onto that backing only once the restore has succeeded, and retires the backing it displaced only once that swap is confirmed, so the source keeps serving its own data until the restored data is in place and any failure leaves it untouched. A serverless source has no dedicated backing to clone and restores onto the archived database instead.
`)
.requiredOption(`--archive-id <archive-id>`, `Backup archive ID to restore`)
.requiredOption(`--services [services...]`, `Array of services to restore`)
.option(`--new-resource-id <new-resource-id>`, `Destination resource ID. Omit to generate a new ID, or pass the archived resource ID to overwrite it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
.option(`--new-resource-id <new-resource-id>`, `Destination resource ID. Omit to restore the archived resource in place, or pass a different ID to restore alongside it as a new resource. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
.option(`--new-resource-name <new-resource-name>`, `Database name. Max length: 128 chars.`)
.action(
actionRunner(
Expand Down
5 changes: 3 additions & 2 deletions lib/commands/services/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,11 @@ If you're creating a new file using one of the Appwrite SDKs, all the chunking l
.requiredOption(`--file-id <file-id>`, `File ID. Choose a custom ID or generate a random ID with \`ID.unique()\`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
.requiredOption(`--file <file>`, `Binary file. Appwrite SDKs provide helpers to handle file input. Learn about file input (https://appwrite.io/docs/products/storage/upload-download#input-file).`)
.option(`--permissions [permissions...]`, `An array of permission strings. By default, only the current user is granted all permissions. Learn more about permissions (https://appwrite.io/docs/permissions).`)
.option(`--folder <folder>`, `Virtual folder to place the file in, for example "photos/2026". Nest folders with \`/\`. Defaults to the bucket root.`)
.action(
actionRunner(
async ({ bucketId, fileId, file, permissions }) =>
parse(await (await getStorageClient()).createFile(bucketId, fileId, file !== undefined ? await resolveFileParam(file) : undefined, permissions)),
async ({ bucketId, fileId, file, permissions, folder }) =>
parse(await (await getStorageClient()).createFile(bucketId, fileId, file !== undefined ? await resolveFileParam(file) : undefined, permissions, folder)),
),
);

Expand Down
7 changes: 4 additions & 3 deletions lib/commands/services/tablesdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,12 @@ const tablesDBUpdateCommand = tablesDB
(value: string | undefined) =>
value === undefined ? true : parseBool(value),
)
.option(`--specification <specification>`, `Database specification. Resizing between dedicated specifications changes cpu, memory, storage and the connection ceiling via a rolling cutover with zero downtime. Moving a \`serverless\` database onto a dedicated specification is a data migration, not a resize.`)
.option(`--replicas <replicas>`, `Number of high availability replicas (0-5) for the dedicated database backing this database. Only valid when the database is backed by a dedicated specification. High availability is enabled when greater than 0.`, parseInteger)
.action(
actionRunner(
async ({ databaseId, name, enabled, replicas }) =>
parse(await (await getTablesDBClient()).update(databaseId, name, enabled, replicas)),
async ({ databaseId, name, enabled, specification, replicas }) =>
parse(await (await getTablesDBClient()).update(databaseId, name, enabled, specification, replicas)),
),
);

Expand All @@ -233,7 +234,7 @@ const tablesDBDeleteCommand = tablesDB

const tablesDBCreateFailoverCommand = tablesDB
.command(`create-failover`)
.description(`Trigger a manual failover for a dedicated database with high availability enabled. Promotes a replica to primary. The failover runs asynchronously; poll the database document for status updates.`)
.description(`Trigger a manual failover for a dedicated database with high availability enabled. Promotes a replica to primary. The failover runs asynchronously; poll the database document for status updates. A database left mid-operation by a failover that did not finish also accepts this call as a repair, provided \`targetReplicaId\` names the member to promote.`)
.requiredOption(`--database-id <database-id>`, `Database ID.`)
.option(`--target-replica-id <target-replica-id>`, `Target replica ID to promote. If not specified, the healthiest replica is selected.`)
.action(
Expand Down
2 changes: 1 addition & 1 deletion lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SDK
export const SDK_TITLE = 'Appwrite';
export const SDK_TITLE_LOWER = 'appwrite';
export const SDK_VERSION = '23.2.0';
export const SDK_VERSION = '24.0.0';
export const SDK_NAME = 'Command Line';
export const SDK_PLATFORM = 'console';
export const SDK_LANGUAGE = 'cli';
Expand Down
2 changes: 0 additions & 2 deletions lib/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
* and read it anywhere with isFlagEnabled("<name>").
*/
const FLAG_ENV_VARS = {
// Browser-based OAuth2 device login for Cloud (otherwise email/password).
oauthLogin: "APPWRITE_CLI_OAUTH_LOGIN",
// Treat localhost/loopback endpoints as Cloud for OAuth login testing.
devCloudLogin: "APPWRITE_CLI_DEV_CLOUD_LOGIN",
} as const;
Expand Down
4 changes: 1 addition & 3 deletions lib/sdks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from "./constants.js";
import { warn } from "./parser.js";
import { isCloudHostname } from "./utils.js";
import { isFlagEnabled } from "./flags.js";
import {
getStoredRefreshToken,
setStoredRefreshToken,
Expand Down Expand Up @@ -87,8 +86,7 @@ export const getValidAccessToken = async (
let legacySessionWarningShown = false;

const warnLegacySession = (): void => {
// Only nudge toward OAuth login when the feature is enabled.
if (legacySessionWarningShown || !isFlagEnabled("oauthLogin")) {
if (legacySessionWarningShown) {
return;
}

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"homepage": "https://appwrite.io/support",
"description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API",
"version": "23.2.0",
"version": "24.0.0",
"license": "BSD-3-Clause",
"main": "dist/index.cjs",
"module": "dist/index.js",
Expand Down Expand Up @@ -51,7 +51,7 @@
"windows-arm64": "bun build cli.ts --compile --minify --target=bun-windows-arm64 --outfile build/appwrite-cli-win-arm64.exe"
},
"dependencies": {
"@appwrite.io/console": "15.6.0",
"@appwrite.io/console": "15.7.0",
"@napi-rs/keyring": "^1.3.0",
"chalk": "4.1.2",
"chokidar": "^3.6.0",
Expand Down
6 changes: 3 additions & 3 deletions scoop/appwrite.config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
"version": "23.2.0",
"version": "24.0.0",
"description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.",
"homepage": "https://github.com/appwrite/sdk-for-cli",
"license": "BSD-3-Clause",
"architecture": {
"64bit": {
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/23.2.0/appwrite-cli-win-x64.exe",
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/24.0.0/appwrite-cli-win-x64.exe",
"bin": [
[
"appwrite-cli-win-x64.exe",
Expand All @@ -15,7 +15,7 @@
]
},
"arm64": {
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/23.2.0/appwrite-cli-win-arm64.exe",
"url": "https://github.com/appwrite/sdk-for-cli/releases/download/24.0.0/appwrite-cli-win-arm64.exe",
"bin": [
[
"appwrite-cli-win-arm64.exe",
Expand Down