mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch 'master' of https://github.com/appwrite/appwrite into feat-functions-refactor
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
name: "Tests"
|
||||
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
tests:
|
||||
name: Unit & E2E
|
||||
runs-on: self-hosted
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -19,16 +18,29 @@ jobs:
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Build Appwrite
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
- name: Prepare Docker
|
||||
run: |
|
||||
export COMPOSE_INTERACTIVE_NO_CLI
|
||||
export DOCKER_BUILDKIT=1
|
||||
export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
docker pull composer:2.0
|
||||
docker pull php:8.0-cli-alpine
|
||||
docker compose build --progress=plain
|
||||
docker compose pull
|
||||
|
||||
- name: Prepare Cache
|
||||
uses: satackey/action-docker-layer-caching@v0.0.11
|
||||
# Ignore the failure of a step and avoid terminating the job.
|
||||
continue-on-error: true
|
||||
|
||||
- name: Build Appwrite
|
||||
run: docker compose build --progress=plain
|
||||
|
||||
- name: Start Appwrite
|
||||
run: |
|
||||
docker compose up -d
|
||||
sleep 30
|
||||
|
||||
- name: Doctor
|
||||
run: docker compose exec -T appwrite doctor
|
||||
|
||||
@@ -37,9 +49,3 @@ jobs:
|
||||
|
||||
- name: Run Tests
|
||||
run: docker compose exec -T appwrite test --debug
|
||||
|
||||
- name: Teardown
|
||||
if: always()
|
||||
run: |
|
||||
docker compose down -v
|
||||
docker ps -aq | xargs docker rm --force
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/bin/bash bash
|
||||
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Missing tag number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]
|
||||
then
|
||||
echo "Missing version number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $(find "./app/db/DBIP/dbip-country-lite-2021-12.mmdb" -mmin +259200)
|
||||
then
|
||||
printf "${RED}GEO country DB has not been updated for more than 6 months. Go to https://db-ip.com/db/download/ip-to-country-lite to download a newer version${NC}\n"
|
||||
fi
|
||||
|
||||
echo 'Starting build...'
|
||||
|
||||
docker build --build-arg VERSION="$2" --tag appwrite/appwrite:"$1" .
|
||||
|
||||
echo 'Pushing build to registry...'
|
||||
|
||||
docker push appwrite/appwrite:"$1"
|
||||
@@ -1 +0,0 @@
|
||||
echo 'Nothing to deploy right now.'
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
dist: focal
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
|
||||
os: linux
|
||||
|
||||
vm:
|
||||
size: large
|
||||
|
||||
language: shell
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- team@appwrite.io
|
||||
|
||||
before_install:
|
||||
# Install latest Docker
|
||||
- curl -fsSL https://get.docker.com | sh
|
||||
# Enable Buildkit in Docker config
|
||||
- echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
|
||||
- mkdir -p $HOME/.docker
|
||||
- echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
|
||||
- sudo service docker start
|
||||
# Login to increase Docker Hub ratelimit
|
||||
- >
|
||||
if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then
|
||||
echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin
|
||||
fi
|
||||
- docker --version
|
||||
# Install latest Compose
|
||||
- sudo rm /usr/local/bin/docker-compose
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
- docker-compose --version
|
||||
# Enable Buildkit
|
||||
- docker buildx create --name travis_builder --use
|
||||
- export COMPOSE_INTERACTIVE_NO_CLI
|
||||
- export DOCKER_BUILDKIT=1
|
||||
- export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
- export BUILDKIT_PROGRESS=plain
|
||||
# Only pass a single runtime for CI stability
|
||||
- echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
# Ensure Travis scripts are executable
|
||||
- chmod -R u+x ./.travis-ci
|
||||
|
||||
install:
|
||||
- docker-compose pull
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
- docker pull composer:2.0
|
||||
- docker pull php:8.0-cli-alpine
|
||||
- docker-compose build
|
||||
- docker-compose up -d
|
||||
- sleep 60
|
||||
|
||||
script:
|
||||
- docker ps -a
|
||||
# Tests should fail if any container is in exited status
|
||||
# - ALL_UP=`docker ps -aq --filter "status=exited"`
|
||||
# - >
|
||||
# if [[ "$ALL_UP" != "" ]]; then
|
||||
# exit 1
|
||||
# fi
|
||||
- docker-compose logs appwrite
|
||||
- docker-compose logs appwrite-realtime
|
||||
- docker-compose logs mariadb
|
||||
- docker-compose logs appwrite-worker-functions
|
||||
- docker-compose exec appwrite doctor
|
||||
- docker-compose exec appwrite vars
|
||||
- docker-compose exec appwrite test --debug
|
||||
|
||||
after_script:
|
||||
# travis re-uses their build nodes so clean them up
|
||||
- docker buildx rm travis_builder
|
||||
|
||||
after_failure:
|
||||
- docker-compose logs appwrite
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
edge: true
|
||||
script: ./.travis-ci/deploy.sh
|
||||
on:
|
||||
repo: appwrite/appwrite
|
||||
branch: deploy
|
||||
@@ -230,7 +230,7 @@ App::get('/v1/database/collections')
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('name', Query::TYPE_SEARCH, [$search]);
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$usage->setParam('database.collections.read', 1);
|
||||
|
||||
@@ -863,7 +863,7 @@ App::post('/v1/functions/:functionId/executions')
|
||||
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
|
||||
}
|
||||
|
||||
$validator = new Authorization($function, 'execute');
|
||||
$validator = new Authorization('execute');
|
||||
|
||||
if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function
|
||||
throw new Exception($validator->getDescription(), 401);
|
||||
|
||||
@@ -620,6 +620,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -675,6 +676,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -739,6 +741,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -803,6 +806,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -855,6 +859,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -911,6 +916,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -963,6 +969,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
@@ -1015,6 +1022,7 @@ $logs = $this->getParam('logs', null);
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
|
||||
@@ -174,7 +174,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
||||
<input type="email" class="full-width" id="user-email" name="email" required autocomplete="off" />
|
||||
|
||||
<label for="user-password">Password</label>
|
||||
<input type="password" class="full-width" id="user-password" name="password" required pattern=".{6,}" title="Six or more characters" autocomplete="off" />
|
||||
<input type="password" class="full-width" id="user-password" name="password" required minlength="8" title="Eight or more characters" autocomplete="off" />
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
<input type="hidden" name="secret" data-ls-bind="{{router.params.secret}}">
|
||||
|
||||
<label>Password</label>
|
||||
<input name="password" type="password" autocomplete="off" placeholder="" required data-forms-password-meter pattern=".{6,}" title="Six or more characters">
|
||||
<input name="password" type="password" autocomplete="off" placeholder="" required data-forms-password-meter minlength="8" title="Eight or more characters">
|
||||
|
||||
<label>Confirm Password</label>
|
||||
<input name="passwordAgain" type="password" autocomplete="off" placeholder="" required data-forms-password-meter pattern=".{6,}" title="Six or more characters">
|
||||
<input name="passwordAgain" type="password" autocomplete="off" placeholder="" required data-forms-password-meter minlength="8" title="Eight or more characters">
|
||||
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-sign-in"></i> Apply</button>
|
||||
</form>
|
||||
|
||||
@@ -37,7 +37,7 @@ $root = ($this->getParam('root') !== 'disabled');
|
||||
|
||||
<input name="email" type="email" class="full-width" autocomplete="email" placeholder="Email" required>
|
||||
|
||||
<input name="password" type="password" class="full-width" autocomplete="off" placeholder="Password" required pattern=".{6,}" title="Six or more characters">
|
||||
<input name="password" type="password" class="full-width" autocomplete="off" placeholder="Password" required minlength="8" title="Eight or more characters">
|
||||
|
||||
<button>Sign In</button>
|
||||
</form>
|
||||
|
||||
@@ -46,7 +46,7 @@ $root = ($this->getParam('root') !== 'disabled');
|
||||
<input name="email" type="email" autocomplete="email" placeholder="" required data-ls-bind="{{router.params.email}}">
|
||||
|
||||
<label>Password</label>
|
||||
<input name="password" type="password" autocomplete="off" placeholder="" required data-forms-password-meter pattern=".{8,}" title="Eight or more characters">
|
||||
<input name="password" type="password" autocomplete="off" placeholder="" required data-forms-password-meter minlength="8" title="Eight or more characters">
|
||||
|
||||
<div class="agree margin-top-large margin-bottom-large">
|
||||
<div class="pull-start margin-end-small margin-bottom">
|
||||
|
||||
@@ -1 +1 @@
|
||||
Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the option id argument, only the session unique ID provider will be deleted.
|
||||
Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the Session ID argument, only the unique session ID provided is deleted.
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class Scope extends TestCase
|
||||
|
||||
protected function getLastEmail():array
|
||||
{
|
||||
sleep(5);
|
||||
sleep(3);
|
||||
|
||||
$emails = json_decode(file_get_contents('http://maildev:1080/email'), true);
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class Scope extends TestCase
|
||||
|
||||
protected function getLastRequest():array
|
||||
{
|
||||
sleep(5);
|
||||
sleep(2);
|
||||
|
||||
$resquest = json_decode(file_get_contents('http://request-catcher:5000/__last_request__'), true);
|
||||
$resquest['data'] = json_decode($resquest['data'], true);
|
||||
@@ -167,4 +167,4 @@ abstract class Scope extends TestCase
|
||||
|
||||
return self::$user[$this->getProject()['$id']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,39 @@ class DatabaseCustomServerTest extends Scope
|
||||
$this->assertCount(0, $collections['body']['collections']);
|
||||
$this->assertEmpty($collections['body']['collections']);
|
||||
|
||||
/**
|
||||
* Test for Search
|
||||
*/
|
||||
$collections = $this->client->call(Client::METHOD_GET, '/database/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'first'
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $collections['body']['sum']);
|
||||
$this->assertEquals('first', $collections['body']['collections'][0]['$id']);
|
||||
|
||||
$collections = $this->client->call(Client::METHOD_GET, '/database/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'Test'
|
||||
]);
|
||||
|
||||
$this->assertEquals(2, $collections['body']['sum']);
|
||||
$this->assertEquals('Test 1', $collections['body']['collections'][0]['name']);
|
||||
$this->assertEquals('Test 2', $collections['body']['collections'][1]['name']);
|
||||
|
||||
$collections = $this->client->call(Client::METHOD_GET, '/database/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'Nonexistent'
|
||||
]);
|
||||
|
||||
$this->assertEquals(0, $collections['body']['sum']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
@@ -224,6 +224,32 @@ class FunctionsCustomClientTest extends Scope
|
||||
];
|
||||
}
|
||||
|
||||
public function testCreateExecutionUnauthorized():array
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test',
|
||||
'execute' => [],
|
||||
'runtime' => 'php-8.0',
|
||||
'timeout' => 10,
|
||||
]);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$function['body']['$id'].'/executions', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'async' => 1,
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $execution['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateCustomExecution
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user