Compare commits

..

5 Commits

Author SHA1 Message Date
Arik Fraimovich
14ea79b1e9 Fix build configuration 2016-08-02 14:02:30 +03:00
Arik Fraimovich
432fe9b8a3 Update version 2016-08-02 13:59:06 +03:00
Arik Fraimovich
33909a1b32 Skip email sending if there are no recipients 2016-08-02 13:56:39 +03:00
Arik Fraimovich
9bca3933e7 Fix #1212: email alerts not being sent 2016-08-02 13:56:22 +03:00
Arik Fraimovich
e1dd1b3f71 Update cirlce.yml to build release_* branches 2016-08-02 13:51:05 +03:00
1485 changed files with 35500 additions and 146698 deletions

3
.bowerrc Normal file
View File

@@ -0,0 +1,3 @@
{
"directory": "rd_ui/app/bower_components"
}

View File

@@ -1,12 +0,0 @@
FROM cypress/browsers:node18.12.0-chrome106-ff106
ENV APP /usr/src/app
WORKDIR $APP
COPY package.json yarn.lock .yarnrc $APP/
COPY viz-lib $APP/viz-lib
RUN npm install yarn@1.22.22 -g && yarn --frozen-lockfile --network-concurrency 1 > /dev/null
COPY . $APP
RUN ./node_modules/.bin/cypress verify

View File

@@ -1,25 +0,0 @@
services:
redash:
build: ../
command: manage version
depends_on:
- postgres
- redis
ports:
- "5000:5000"
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
POSTGRES_PASSWORD: "FmTKs5vX52ufKR1rd8tn4MoSP7zvCJwb"
REDASH_DATABASE_URL: "postgresql://postgres:FmTKs5vX52ufKR1rd8tn4MoSP7zvCJwb@postgres/postgres"
REDASH_COOKIE_SECRET: "2H9gNG9obnAQ9qnR9BDTQUph6CbXKCzF"
redis:
image: redis:7-alpine
restart: unless-stopped
postgres:
image: pgautoupgrade/pgautoupgrade:latest
command: "postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=OFF"
restart: unless-stopped
environment:
POSTGRES_HOST_AUTH_METHOD: "trust"

View File

@@ -1,73 +0,0 @@
x-redash-service: &redash-service
build:
context: ../
args:
install_groups: "main"
code_coverage: ${CODE_COVERAGE}
x-redash-environment: &redash-environment
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
POSTGRES_PASSWORD: "FmTKs5vX52ufKR1rd8tn4MoSP7zvCJwb"
REDASH_DATABASE_URL: "postgresql://postgres:FmTKs5vX52ufKR1rd8tn4MoSP7zvCJwb@postgres/postgres"
REDASH_RATELIMIT_ENABLED: "false"
REDASH_ENFORCE_CSRF: "true"
REDASH_COOKIE_SECRET: "2H9gNG9obnAQ9qnR9BDTQUph6CbXKCzF"
services:
server:
<<: *redash-service
command: server
depends_on:
- postgres
- redis
ports:
- "5000:5000"
environment:
<<: *redash-environment
PYTHONUNBUFFERED: 0
scheduler:
<<: *redash-service
command: scheduler
depends_on:
- server
environment:
<<: *redash-environment
worker:
<<: *redash-service
command: worker
depends_on:
- server
environment:
<<: *redash-environment
PYTHONUNBUFFERED: 0
cypress:
ipc: host
build:
context: ../
dockerfile: .ci/Dockerfile.cypress
depends_on:
- server
- worker
- scheduler
environment:
CYPRESS_baseUrl: "http://server:5000"
CYPRESS_coverage: ${CODE_COVERAGE}
PERCY_TOKEN: ${PERCY_TOKEN}
PERCY_BRANCH: ${CIRCLE_BRANCH}
PERCY_COMMIT: ${CIRCLE_SHA1}
PERCY_PULL_REQUEST: ${CIRCLE_PR_NUMBER}
COMMIT_INFO_BRANCH: ${CIRCLE_BRANCH}
COMMIT_INFO_MESSAGE: ${COMMIT_INFO_MESSAGE}
COMMIT_INFO_AUTHOR: ${CIRCLE_USERNAME}
COMMIT_INFO_SHA: ${CIRCLE_SHA1}
COMMIT_INFO_REMOTE: ${CIRCLE_REPOSITORY_URL}
CYPRESS_PROJECT_ID: ${CYPRESS_PROJECT_ID}
CYPRESS_RECORD_KEY: ${CYPRESS_RECORD_KEY}
redis:
image: redis:7-alpine
restart: unless-stopped
postgres:
image: pgautoupgrade/pgautoupgrade:latest
command: "postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=OFF"
restart: unless-stopped
environment:
POSTGRES_HOST_AUTH_METHOD: "trust"

View File

@@ -1,39 +0,0 @@
#!/bin/bash
# This script only needs to run on the main Redash repo
if [ "${GITHUB_REPOSITORY}" != "getredash/redash" ]; then
echo "Skipping image build for Docker Hub, as this isn't the main Redash repository"
exit 0
fi
if [ "${GITHUB_REF_NAME}" != "master" ] && [ "${GITHUB_REF_NAME}" != "preview-image" ]; then
echo "Skipping image build for Docker Hub, as this isn't the 'master' nor 'preview-image' branch"
exit 0
fi
if [ "x${DOCKER_USER}" = "x" ] || [ "x${DOCKER_PASS}" = "x" ]; then
echo "Skipping image build for Docker Hub, as the login details aren't available"
exit 0
fi
set -e
VERSION=$(jq -r .version package.json)
VERSION_TAG="$VERSION.b${GITHUB_RUN_ID}.${GITHUB_RUN_NUMBER}"
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
docker login -u "${DOCKER_USER}" -p "${DOCKER_PASS}"
DOCKERHUB_REPO="redash/redash"
DOCKER_TAGS="-t redash/redash:preview -t redash/preview:${VERSION_TAG}"
# Build the docker container
docker build --build-arg install_groups="main,all_ds,dev" ${DOCKER_TAGS} .
# Push the container to the preview build locations
docker push "${DOCKERHUB_REPO}:preview"
docker push "redash/preview:${VERSION_TAG}"
echo "Built: ${VERSION_TAG}"

View File

@@ -1,9 +0,0 @@
#!/bin/bash
NAME=redash
VERSION=$(jq -r .version package.json)
FULL_VERSION=$VERSION+b$CIRCLE_BUILD_NUM
FILENAME=$NAME.$FULL_VERSION.tar.gz
mkdir -p /tmp/artifacts/
tar -zcv -f /tmp/artifacts/$FILENAME --exclude=".git" --exclude="optipng*" --exclude="cypress" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" *

View File

@@ -1,6 +0,0 @@
#!/bin/bash
VERSION=$(jq -r .version package.json)
FULL_VERSION=${VERSION}+b${GITHUB_RUN_ID}.${GITHUB_RUN_NUMBER}
sed -ri "s/^__version__ = '([A-Za-z0-9.-]*)'/__version__ = '${FULL_VERSION}'/" redash/__init__.py
sed -i "s/dev/${GITHUB_SHA}/" client/app/version.json

View File

@@ -1,9 +1,5 @@
[run]
branch = True
source = redash
[report]
omit =
*/settings.py
*/python?.?/*
show_missing = True
*/site-packages/nose/*

View File

@@ -1,14 +1,4 @@
client/.tmp/
node_modules/
viz-lib/node_modules/
.tmp/
.venv/
venv/
rd_ui/.tmp/
rd_ui/node_modules/
.git/
/.codeclimate.yml
/.coverage
/coverage.xml
/.circleci/
/.github/
/netlify.toml
/setup/
.vagrant/

View File

@@ -1,14 +0,0 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.py]
indent_style = space
indent_size = 4
[*.{js,jsx,css,less,html}]
indent_style = space
indent_size = 2

5
.env.example Normal file
View File

@@ -0,0 +1,5 @@
REDASH_STATIC_ASSETS_PATH="../rd_ui/app/"
REDASH_LOG_LEVEL="INFO"
REDASH_REDIS_URL=redis://localhost:6379/1
REDASH_DATABASE_URL="postgresql://redash"
REDASH_COOKIE_SECRET=veryverysecret

24
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,24 @@
Welcome to Redash's GitHub repo! 👋🎉
Do you need help or have a question? Checkout the Support category in our discussion forum: https://discuss.redash.io/c/support.
Got an idea for a new feature? Check if it isn't on the roadmap already: http://bit.ly/redash-roadmap and start a new discussion in the features category: https://discuss.redash.io/c/feature-requests 🌟.
Found a bug? Please fill out the sections below... thank you 👍
### Issue Summary
A summary of the issue and the browser/OS environment in which it occurs.
### Steps to Reproduce
1. This is the first step
2. This is the second step, etc.
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?
### Technical details:
* Redash Version:
* Browser/OS:
* How did you install Redash:

View File

@@ -1,34 +0,0 @@
---
name: "\U0001F41B Bug report"
about: Report reproducible software issues so we can improve
---
<!--
We use GitHub only for bug reports 🐛
Anything else should be a discussion: https://github.com/getredash/redash/discussions/ 👫
🚨For support, help & questions use https://github.com/getredash/redash/discussions/categories/q-a
💡For feature requests & ideas use https://github.com/getredash/redash/discussions/categories/ideas
**Found a security vulnerability?** Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.
-->
### Issue Summary
A summary of the issue and the browser/OS environment in which it occurs.
### Steps to Reproduce
1. This is the first step
2. This is the second step, etc.
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?
### Technical details:
* Redash Version:
* Browser/OS:
* How did you install Redash:

View File

@@ -1,17 +0,0 @@
---
name: "\U0001F4A1Anything else"
about: "For help, support, features & ideas - please use Discussions \U0001F46B "
labels: "Support Question"
---
We use GitHub only for bug reports 🐛
Anything else should be a discussion: https://github.com/getredash/redash/discussions/ 👫
🚨For support, help & questions use https://github.com/getredash/redash/discussions/categories/q-a
💡For feature requests & ideas use https://github.com/getredash/redash/discussions/categories/ideas
Alternatively, check out these resources below. Thanks! 😁.
- [Discussions](https://github.com/getredash/redash/discussions/)
- [Knowledge Base](https://redash.io/help)

View File

@@ -1,26 +0,0 @@
## What type of PR is this?
<!-- Check all that apply, delete what doesn't apply. -->
- [ ] Refactor
- [ ] Feature
- [ ] Bug Fix
- [ ] New Query Runner (Data Source)
- [ ] New Alert Destination
- [ ] Other
## Description
<!-- In case of adding / modifying a query runner, please specify which version(s) you expect are compatible. -->
## How is this tested?
- [ ] Unit tests (pytest, jest)
- [ ] E2E Tests (Cypress)
- [ ] Manually
- [ ] N/A
<!-- If Manually, please describe. -->
## Related Tickets & Documents
<!-- If applicable, please include a link to your documentation PR against getredash/website -->
## Mobile & Desktop Screenshots/Recordings (if there are UI changes)

5
.github/config.yml vendored
View File

@@ -1,5 +0,0 @@
# https://github.com/behaviorbot/request-info?installation_id=189571
requestInfoLabelToAdd: needs-more-info
requestInfoReplyComment: >
We would appreciate it if you could provide us with more info about this issue/pr!

View File

@@ -1,7 +0,0 @@
# Configuration for weekly-digest - https://github.com/apps/weekly-digest
publishDay: mon
canPublishIssues: true
canPublishPullRequests: true
canPublishContributors: true
canPublishStargazers: true
canPublishCommits: true

View File

@@ -1,177 +0,0 @@
name: Tests
on:
push:
branches:
- master
pull_request:
branches:
- master
env:
NODE_VERSION: 18
YARN_VERSION: 1.22.22
jobs:
backend-lint:
runs-on: ubuntu-22.04
steps:
- if: github.event.pull_request.mergeable == 'false'
name: Exit if PR is not mergeable
run: exit 1
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-python@v5
with:
python-version: '3.8'
- run: sudo pip install black==23.1.0 ruff==0.0.287
- run: ruff check .
- run: black --check .
backend-unit-tests:
runs-on: ubuntu-22.04
needs: backend-lint
env:
COMPOSE_FILE: .ci/compose.ci.yaml
COMPOSE_PROJECT_NAME: redash
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
steps:
- if: github.event.pull_request.mergeable == 'false'
name: Exit if PR is not mergeable
run: exit 1
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- name: Build Docker Images
run: |
set -x
docker compose build --build-arg install_groups="main,all_ds,dev" --build-arg skip_frontend_build=true
docker compose up -d
sleep 10
- name: Create Test Database
run: docker compose -p redash run --rm postgres psql -h postgres -U postgres -c "create database tests;"
- name: List Enabled Query Runners
run: docker compose -p redash run --rm redash manage ds list_types
- name: Run Tests
run: docker compose -p redash run --name tests redash tests --junitxml=junit.xml --cov-report=xml --cov=redash --cov-config=.coveragerc tests/
- name: Copy Test Results
run: |
mkdir -p /tmp/test-results/unit-tests
docker cp tests:/app/coverage.xml ./coverage.xml
docker cp tests:/app/junit.xml /tmp/test-results/unit-tests/results.xml
# - name: Upload coverage reports to Codecov
# uses: codecov/codecov-action@v3
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
- name: Store Test Results
uses: actions/upload-artifact@v4
with:
name: backend-test-results
path: /tmp/test-results
- name: Store Coverage Results
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage.xml
frontend-lint:
runs-on: ubuntu-22.04
steps:
- if: github.event.pull_request.mergeable == 'false'
name: Exit if PR is not mergeable
run: exit 1
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Install Dependencies
run: |
npm install --global --force yarn@$YARN_VERSION
yarn cache clean && yarn --frozen-lockfile --network-concurrency 1
- name: Run Lint
run: yarn lint:ci
- name: Store Test Results
uses: actions/upload-artifact@v4
with:
name: frontend-test-results
path: /tmp/test-results
frontend-unit-tests:
runs-on: ubuntu-22.04
needs: frontend-lint
steps:
- if: github.event.pull_request.mergeable == 'false'
name: Exit if PR is not mergeable
run: exit 1
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Install Dependencies
run: |
npm install --global --force yarn@$YARN_VERSION
yarn cache clean && yarn --frozen-lockfile --network-concurrency 1
- name: Run App Tests
run: yarn test
- name: Run Visualizations Tests
run: cd viz-lib && yarn test
- run: yarn lint
frontend-e2e-tests:
runs-on: ubuntu-22.04
needs: frontend-lint
env:
COMPOSE_FILE: .ci/compose.cypress.yaml
COMPOSE_PROJECT_NAME: cypress
CYPRESS_INSTALL_BINARY: 0
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 1
# PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
# CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }}
# CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
steps:
- if: github.event.pull_request.mergeable == 'false'
name: Exit if PR is not mergeable
run: exit 1
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Enable Code Coverage Report For Master Branch
if: endsWith(github.ref, '/master')
run: |
echo "CODE_COVERAGE=true" >> "$GITHUB_ENV"
- name: Install Dependencies
run: |
npm install --global --force yarn@$YARN_VERSION
yarn cache clean && yarn --frozen-lockfile --network-concurrency 1
- name: Setup Redash Server
run: |
set -x
yarn cypress build
yarn cypress start -- --skip-db-seed
docker compose run cypress yarn cypress db-seed
- name: Execute Cypress Tests
run: yarn cypress run-ci
- name: "Failure: output container logs to console"
if: failure()
run: docker compose logs
- name: Copy Code Coverage Results
run: docker cp cypress:/usr/src/app/coverage ./coverage || true
- name: Store Coverage Results
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage

View File

@@ -1,86 +0,0 @@
name: Periodic Snapshot
on:
schedule:
- cron: '10 0 1 * *' # 10 minutes after midnight on the first day of every month
workflow_dispatch:
inputs:
bump:
description: 'Bump the last digit of the version'
required: false
type: boolean
version:
description: 'Specific version to set'
required: false
default: ''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
actions: write
contents: write
jobs:
bump-version-and-tag:
runs-on: ubuntu-latest
if: github.ref_name == github.event.repository.default_branch
steps:
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.ACTION_PUSH_KEY }}
- run: |
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
# Function to bump the version
bump_version() {
local version="$1"
local IFS=.
read -r major minor patch <<< "$version"
patch=$((patch + 1))
echo "$major.$minor.$patch-dev"
}
# Determine the new version tag
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
BUMP_INPUT="${{ github.event.inputs.bump }}"
SPECIFIC_VERSION="${{ github.event.inputs.version }}"
# Check if both bump and specific version are provided
if [ "$BUMP_INPUT" = "true" ] && [ -n "$SPECIFIC_VERSION" ]; then
echo "::error::Error: Cannot specify both bump and specific version."
exit 1
fi
if [ -n "$SPECIFIC_VERSION" ]; then
TAG_NAME="$SPECIFIC_VERSION-dev"
elif [ "$BUMP_INPUT" = "true" ]; then
CURRENT_VERSION=$(grep '"version":' package.json | awk -F\" '{print $4}')
TAG_NAME=$(bump_version "$CURRENT_VERSION")
else
echo "No version bump or specific version provided for manual dispatch."
exit 1
fi
else
TAG_NAME="$(date +%y.%m).0-dev"
fi
echo "New version tag: $TAG_NAME"
# Update version in files
gawk -i inplace -F: -v q=\" -v tag=${TAG_NAME} '/^ "version": / { print $1 FS, q tag q ","; next} { print }' package.json
gawk -i inplace -F= -v q=\" -v tag=${TAG_NAME} '/^__version__ =/ { print $1 FS, q tag q; next} { print }' redash/__init__.py
gawk -i inplace -F= -v q=\" -v tag=${TAG_NAME} '/^version =/ { print $1 FS, q tag q; next} { print }' pyproject.toml
git add package.json redash/__init__.py pyproject.toml
git commit -m "Snapshot: ${TAG_NAME}"
git tag ${TAG_NAME}
git push --atomic origin master refs/tags/${TAG_NAME}
# Run the 'preview-image' workflow if run this workflow manually
# For more information, please see the: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
if [ "$BUMP_INPUT" = "true" ] || [ -n "$SPECIFIC_VERSION" ]; then
gh workflow run preview-image.yml --ref $TAG_NAME
fi

View File

@@ -1,185 +0,0 @@
name: Preview Image
on:
push:
tags:
- '*-dev'
workflow_dispatch:
inputs:
dockerRepository:
description: 'Docker repository'
required: true
default: 'preview'
type: choice
options:
- preview
- redash
env:
NODE_VERSION: 18
jobs:
build-skip-check:
runs-on: ubuntu-22.04
outputs:
skip: ${{ steps.skip-check.outputs.skip }}
steps:
- name: Skip?
id: skip-check
run: |
if [[ "${{ vars.DOCKER_USER }}" == '' ]]; then
echo 'Docker user is empty. Skipping build+push'
echo skip=true >> "$GITHUB_OUTPUT"
elif [[ "${{ secrets.DOCKER_PASS }}" == '' ]]; then
echo 'Docker password is empty. Skipping build+push'
echo skip=true >> "$GITHUB_OUTPUT"
elif [[ "${{ vars.DOCKER_REPOSITORY }}" == '' ]]; then
echo 'Docker repository is empty. Skipping build+push'
echo skip=true >> "$GITHUB_OUTPUT"
else
echo 'Docker user and password are set and branch is `master`.'
echo 'Building + pushing `preview` image.'
echo skip=false >> "$GITHUB_OUTPUT"
fi
build-docker-image:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
arch:
- amd64
- arm64
include:
- arch: amd64
os: ubuntu-22.04
- arch: arm64
os: ubuntu-22.04-arm
outputs:
VERSION_TAG: ${{ steps.version.outputs.VERSION_TAG }}
needs:
- build-skip-check
if: needs.build-skip-check.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.push.after }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASS }}
- name: Install Dependencies
env:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true
run: |
npm install --global --force yarn@1.22.22
yarn cache clean && yarn --frozen-lockfile --network-concurrency 1
- name: Set version
id: version
run: |
set -x
.ci/update_version
VERSION_TAG=$(jq -r .version package.json)
echo "VERSION_TAG=$VERSION_TAG" >> "$GITHUB_OUTPUT"
- name: Build and push preview image to Docker Hub
id: build-preview
uses: docker/build-push-action@v4
if: ${{ github.event.inputs.dockerRepository == 'preview' || !github.event.workflow_run }}
with:
tags: |
${{ vars.DOCKER_REPOSITORY }}/redash
${{ vars.DOCKER_REPOSITORY }}/preview
context: .
build-args: |
test_all_deps=true
outputs: type=image,push-by-digest=true,push=true
cache-from: type=gha,scope=${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ matrix.arch }}
env:
DOCKER_CONTENT_TRUST: true
- name: Build and push release image to Docker Hub
id: build-release
uses: docker/build-push-action@v4
if: ${{ github.event.inputs.dockerRepository == 'redash' }}
with:
tags: |
${{ vars.DOCKER_REPOSITORY }}/redash:${{ steps.version.outputs.VERSION_TAG }}
context: .
build-args: |
test_all_deps=true
outputs: type=image,push-by-digest=true,push=true
cache-from: type=gha,scope=${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ matrix.arch }}
env:
DOCKER_CONTENT_TRUST: true
- name: "Failure: output container logs to console"
if: failure()
run: docker compose logs
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
if [[ "${{ github.event.inputs.dockerRepository }}" == 'preview' || !github.event.workflow_run ]]; then
digest="${{ steps.build-preview.outputs.digest}}"
else
digest="${{ steps.build-release.outputs.digest}}"
fi
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.arch }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
merge-docker-image:
runs-on: ubuntu-22.04
needs: build-docker-image
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASS }}
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Create and push manifest for the preview image
if: ${{ github.event.inputs.dockerRepository == 'preview' || !github.event.workflow_run }}
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create -t ${{ vars.DOCKER_REPOSITORY }}/redash:preview \
$(printf '${{ vars.DOCKER_REPOSITORY }}/redash:preview@sha256:%s ' *)
docker buildx imagetools create -t ${{ vars.DOCKER_REPOSITORY }}/preview:${{ needs.build-docker-image.outputs.VERSION_TAG }} \
$(printf '${{ vars.DOCKER_REPOSITORY }}/preview:${{ needs.build-docker-image.outputs.VERSION_TAG }}@sha256:%s ' *)
- name: Create and push manifest for the release image
if: ${{ github.event.inputs.dockerRepository == 'redash' }}
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create -t ${{ vars.DOCKER_REPOSITORY }}/redash:${{ needs.build-docker-image.outputs.VERSION_TAG }} \
$(printf '${{ vars.DOCKER_REPOSITORY }}/redash:${{ needs.build-docker-image.outputs.VERSION_TAG }}@sha256:%s ' *)

View File

@@ -1,36 +0,0 @@
name: Restyled
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
restyled:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: restyled-io/actions/setup@v4
- id: restyler
uses: restyled-io/actions/run@v4
with:
fail-on-differences: true
- if: |
!cancelled() &&
steps.restyler.outputs.success == 'true' &&
github.event.pull_request.head.repo.full_name == github.repository
uses: peter-evans/create-pull-request@v6
with:
base: ${{ steps.restyler.outputs.restyled-base }}
branch: ${{ steps.restyler.outputs.restyled-head }}
title: ${{ steps.restyler.outputs.restyled-title }}
body: ${{ steps.restyler.outputs.restyled-body }}
labels: "restyled"
reviewers: ${{ github.event.pull_request.user.login }}
delete-branch: true

27
.gitignore vendored
View File

@@ -1,30 +1,29 @@
.venv
venv/
.cache
.coverage.*
.coveralls.yml
.idea
*.pyc
.nyc_output
coverage
.coverage
coverage.xml
client/dist
rd_ui/dist
.DS_Store
celerybeat-schedule*
.#*
\#*#
*~
_build
.vscode
# Vagrant related
.vagrant
Berksfile.lock
redash/dump.rdb
.env
.tool-versions
.ruby-version
venv
dump.rdb
# Docker related
docker-compose.yml
node_modules
.tmp
.sass-cache
npm-debug.log
client/cypress/screenshots
client/cypress/videos
rd_ui/app/bower_components

2
.landscape.yaml Normal file
View File

@@ -0,0 +1,2 @@
ignore-paths:
- migrations

1
.npmrc
View File

@@ -1 +0,0 @@
engine-strict = true

1
.nvmrc
View File

@@ -1 +0,0 @@
v18

View File

@@ -1,10 +0,0 @@
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.0.287"
hooks:
- id: ruff

View File

@@ -1,68 +0,0 @@
enabled: true
auto: false
# Open Restyle PRs?
pull_requests: true
# Leave comments on the original PR linking to the Restyle PR?
comments: true
# Set commit statuses on the original PR?
statuses:
# Red status in the case of differences found
differences: true
# Green status in the case of no differences found
no_differences: true
# Red status if we encounter errors restyling
error: true
# Request review on the Restyle PR?
#
# Possible values:
#
# author: From the author of the original PR
# owner: From the owner of the repository
# none: Don't
#
# One value will apply to both origin and forked PRs, but you can also specify
# separate values.
#
# request_review:
# origin: author
# forked: owner
#
request_review: author
# Add labels to any created Restyle PRs
#
# These can be used to tell other automation to avoid our PRs.
#
labels:
- restyled
- "Skip CI"
# Labels to ignore
#
# PRs with any of these labels will be ignored by Restyled.
#
# ignore_labels:
# - restyled-ignore
# Restylers to run, and how
restylers:
- name: black
image: restyled/restyler-black:v24.4.2
include:
- redash
- tests
- migrations/versions
- name: prettier
image: restyled/restyler-prettier:v3.3.2-2
command:
- prettier
- --write
include:
- client/app/**/*.js
- client/app/**/*.jsx
- client/cypress/**/*.js

2
.yarn/.gitignore vendored
View File

@@ -1,2 +0,0 @@
*
!.gitignore

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,21 @@ Thank you for taking the time to contribute! :tada::+1:
The following is a set of guidelines for contributing to Redash. These are guidelines, not rules, please use your best judgement and feel free to propose changes to this document in a pull request.
:star: If you're already here and love the project, please make sure to press the Star button. :star:
## Quick Links:
- [Feature Roadmap](https://trello.com/b/b2LUHU7A/re-dash-roadmap)
- [Feature Requests](https://discuss.redash.io/c/feature-requests)
- [Gitter Chat](https://gitter.im/getredash/redash) or [Slack](https://slack.redash.io)
- [Documentation](http://docs.redash.io)
- [Blog](http://blog.redash.io/)
- [Twitter](https://twitter.com/getredash)
---
:star: If you already here and love the project, please make sure to press the Star button. :star:
---
## Table of Contents
[How can I contribute?](#how-can-i-contribute)
@@ -14,19 +28,12 @@ The following is a set of guidelines for contributing to Redash. These are guide
- [Pull Requests](#pull-requests)
- [Documentation](#documentation)
- Design?
[Additional Notes](#additional-notes)
[Addtional Notes](#additional-notes)
- [Release Method](#release-method)
- [Code of Conduct](#code-of-conduct)
## Quick Links:
- [User Forum](https://github.com/getredash/redash/discussions)
- [Documentation](https://redash.io/help/)
---
## How can I contribute?
### Reporting Bugs
@@ -34,68 +41,39 @@ The following is a set of guidelines for contributing to Redash. These are guide
When creating a new bug report, please make sure to:
- Search for existing issues first. If you find a previous report of your issue, please update the existing issue with additional information instead of creating a new one.
- If you are not sure if your issue is really a bug or just some configuration/setup problem, please start a [Q&A discussion](https://github.com/getredash/redash/discussions/new?category=q-a) first. Unless you can provide clear steps to reproduce, it's probably better to start with a discussion and later to open an issue.
- If you are not sure if your issue is really a bug or just some configuration/setup problem, please start a discussion in [the support forum](https://discuss.redash.io/c/support) first. Unless you can provide clear steps to reproduce, it's probably better to start with a thread in the forum and later to open an issue.
- If you still decide to open an issue, please review the template and guidelines and include as much details as possible.
### Suggesting Enhancements / Feature Requests
If you would like to suggest an enhancement or ask for a new feature:
- Please check [the Ideas discussions](https://github.com/getredash/redash/discussions/categories/ideas) for existing threads about what you want to suggest/ask. If there is, feel free to upvote it to signal interest or add your comments.
- If there is no open thread, you're welcome to start one to have a discussion about what you want to suggest. Try to provide as much details and context as possible and include information about *the problem you want to solve* rather only *your proposed solution*.
If you would like to suggest an enchancement or ask for a new feature:
- Please check [the roadmap](https://trello.com/b/b2LUHU7A/re-dash-roadmap) for existing Trello card for what you want to suggest/ask. If there is, feel free to upvote it to signal interest or add your comments.
- If there is no existing card, open a thread in [the forum](https://discuss.redash.io/c/feature-requests) to start a discussion about what you want to suggest. Try to provide as much details and context as possible and include information about *the problem you want to solve* rather only *your proposed solution*.
### Pull Requests
**Code contributions are welcomed**. For big changes or significant features, it's usually better to reach out first and discuss what you want to implement and how (we recommend reading: [Pull Request First](https://medium.com/practical-blend/pull-request-first-f6bb667a9b6#.ozlqxvj36)). This is to make sure that what you want to implement is aligned with our goals for the project and that no one else is already working on it.
#### Criteria for Review / Merging
When you open your pull request, please follow this repositorys PR template carefully:
- Indicate the type of change
- If you implement multiple unrelated features, bug fixes, or refactors please split them into individual pull requests.
- Describe the change
- If fixing a bug, please describe the bug or link to an existing github issue / forum discussion
- Include UI screenshots / GIFs whenever possible
- **Code contributions are welcomed**. For big changes or significant features, it's usually better to reach out first and discuss what you want to implement and how (we recommend reading: [Pull Request First](https://medium.com/practical-blend/pull-request-first-f6bb667a9b6#.ozlqxvj36)). This to make sure that what you want to implement is aligned with our goals for the project and that no one else is already working on it.
- Include screenshots and animated GIFs in your pull request whenever possible.
- Please add [documentation](#documentation) for new features or changes in functionality along with the code.
- Please follow existing code style:
- Python: we use [Black](https://github.com/psf/black) to auto format the code.
- Javascript: we use [Prettier](https://github.com/prettier/prettier) to auto-format the code.
#### Initial Review (1 week)
During this phase, a team member will apply the “Team Review” label if a pull request meets our criteria or a “Needs More Information” label if not. If more information is required, the team member will comment which criteria have not been met.
If your pull request receives the “Needs More Information” label, please make the requested changes and then remove the label. This resets the 1 week timer for an initial review.
Stale pull requests that remain untouched in “Needs More Information” for more than 4 weeks will be closed.
If a team member closes your pull request, you may reopen it after you have made the changes requested during initial review. After you make these changes, remove the “Needs More Information” label. This again resets the timer for another initial review.
#### Full Review (2 weeks)
After the “Team Review” label is applied, a member of the core team will review the PR within 2 weeks.
Reviews will approve, request changes, or ask questions to discuss areas of uncertainty. After youve responded, a member of the team will re-review within one week.
#### Merging (1 week)
After your pull request has been approved, a member of the core team will merge the pull request within a week.
- Please follow existing code style. We use PEP8 for Python and sensible style for Javascript.
### Documentation
The project's documentation can be found at [https://redash.io/help/](https://redash.io/help/). The [documentation sources](https://github.com/getredash/website/tree/master/src/pages/kb) are hosted on GitHub. To contribute edits / new pages, you can use GitHub's interface. Click the "Edit on GitHub" link on the documentation page to quickly open the edit interface.
The project's documentation can be found at [docs.redash.io](http://docs.redash.io/). The [documentation sources](https://github.com/getredash/redash/tree/master/docs) are managed along with the code and to contribute edits / new pages, you can use GitHub's interface. Click the "Edit on GitHub" link on the documentation page to quickly open the edit interface.
The pages are written in *reStructuredText* format, which is very similar to Markdown.
## Additional Notes
### Release Method
We publish a stable release every ~3-4 months, although the goal is to get to a stable release every month.
We publish a stable release every ~2 months, although the goal is to get to a stable release every month. You can see the change log on [GitHub releases page](http://github.com/getredash/redash/releases).
Every build of the master branch updates the *redash/redash:preview* Docker Image. These releases are usually stable, but might contain regressions and therefore recommended for "advanced users" only.
Every build of the master branch updates the latest *RC release*. These releases are usually stable, but might contain regressions and therefore recommended for "advanced users" only.
When we release a new stable release, we also update the *latest* Docker image tag, the EC2 AMIs and GCE images.
## Code of Conduct
This project adheres to the Contributor Covenant [code of conduct](https://redash.io/community/code_of_conduct). By participating, you are expected to uphold this code. Please report unacceptable behavior to team@redash.io.
This project adheres to the Contributor Covenant [code of conduct](http://redash.io/community/code_of_conduct). By participating, you are expected to uphold this code. Please report unacceptable behavior to team@redash.io.

View File

@@ -1,120 +1,53 @@
FROM node:18-bookworm AS frontend-builder
RUN npm install --global --force yarn@1.22.22
# Controls whether to build the frontend assets
ARG skip_frontend_build
ENV CYPRESS_INSTALL_BINARY=0
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
RUN useradd -m -d /frontend redash
USER redash
WORKDIR /frontend
COPY --chown=redash package.json yarn.lock .yarnrc /frontend/
COPY --chown=redash viz-lib /frontend/viz-lib
COPY --chown=redash scripts /frontend/scripts
# Controls whether to instrument code for coverage information
ARG code_coverage
ENV BABEL_ENV=${code_coverage:+test}
# Avoid issues caused by lags in disk and network I/O speeds when working on top of QEMU emulation for multi-platform image building.
RUN yarn config set network-timeout 300000
RUN if [ "x$skip_frontend_build" = "x" ] ; then yarn --frozen-lockfile --network-concurrency 1; fi
COPY --chown=redash client /frontend/client
COPY --chown=redash webpack.config.js /frontend/
RUN <<EOF
if [ "x$skip_frontend_build" = "x" ]; then
yarn build
else
mkdir -p /frontend/client/dist
touch /frontend/client/dist/multi_org.html
touch /frontend/client/dist/index.html
fi
EOF
FROM python:3.10-slim-bookworm
EXPOSE 5000
RUN useradd --create-home redash
FROM ubuntu:trusty
# Ubuntu packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
pkg-config \
curl \
gnupg \
build-essential \
pwgen \
libffi-dev \
sudo \
git-core \
# Kerberos, needed for MS SQL Python driver to compile on arm64
libkrb5-dev \
apt-get install -y python-pip python-dev curl build-essential pwgen libffi-dev sudo git-core wget \
# Postgres client
libpq-dev \
# ODBC support:
g++ unixodbc-dev \
# for SAML
xmlsec1 \
# Additional packages required for data sources:
libssl-dev \
default-libmysqlclient-dev \
freetds-dev \
libsasl2-dev \
unzip \
libsasl2-modules-gssapi-mit && \
libssl-dev libmysqlclient-dev freetds-dev libsasl2-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Users creation
RUN useradd --system --comment " " --create-home redash
ARG TARGETPLATFORM
ARG databricks_odbc_driver_url=https://databricks-bi-artifacts.s3.us-east-2.amazonaws.com/simbaspark-drivers/odbc/2.6.26/SimbaSparkODBC-2.6.26.1045-Debian-64bit.zip
RUN <<EOF
if [ "$TARGETPLATFORM" = "linux/amd64" ]; then
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
curl https://packages.microsoft.com/config/debian/12/prod.list > /etc/apt/sources.list.d/mssql-release.list
apt-get update
ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18
apt-get clean
rm -rf /var/lib/apt/lists/*
curl "$databricks_odbc_driver_url" --location --output /tmp/simba_odbc.zip
chmod 600 /tmp/simba_odbc.zip
unzip /tmp/simba_odbc.zip -d /tmp/simba
dpkg -i /tmp/simba/*.deb
printf "[Simba]\nDriver = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbcinst.ini
rm /tmp/simba_odbc.zip
rm -rf /tmp/simba
fi
EOF
# Pip requirements for all data source types
RUN pip install -U setuptools==23.1.0 && \
pip install supervisor==3.1.2
WORKDIR /app
COPY . /opt/redash/current
RUN chown -R redash /opt/redash/current
ENV POETRY_VERSION=1.8.3
ENV POETRY_HOME=/etc/poetry
ENV POETRY_VIRTUALENVS_CREATE=false
RUN curl -sSL https://install.python-poetry.org | python3 -
# Setting working directory
WORKDIR /opt/redash/current
# Avoid crashes, including corrupted cache artifacts, when building multi-platform images with GitHub Actions.
RUN /etc/poetry/bin/poetry cache clear pypi --all
ENV REDASH_STATIC_ASSETS_PATH="../rd_ui/dist/"
COPY pyproject.toml poetry.lock ./
# Install project specific dependencies
RUN pip install -r requirements_all_ds.txt && \
pip install -r requirements.txt
ARG POETRY_OPTIONS="--no-root --no-interaction --no-ansi"
# for LDAP authentication, install with `ldap3` group
# disabled by default due to GPL license conflict
ARG install_groups="main,all_ds,dev"
RUN /etc/poetry/bin/poetry install --only $install_groups $POETRY_OPTIONS
RUN curl https://deb.nodesource.com/setup_4.x | bash - && \
apt-get install -y nodejs && \
sudo -u redash -H make deps && \
rm -rf node_modules rd_ui/node_modules /home/redash/.npm /home/redash/.cache && \
apt-get purge -y nodejs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY --chown=redash . /app
COPY --from=frontend-builder --chown=redash /frontend/client/dist /app/client/dist
RUN chown redash /app
USER redash
# Setup supervisord
RUN mkdir -p /opt/redash/supervisord && \
mkdir -p /opt/redash/logs && \
cp /opt/redash/current/setup/docker/supervisord/supervisord.conf /opt/redash/supervisord/supervisord.conf
ENTRYPOINT ["/app/bin/docker-entrypoint"]
CMD ["server"]
# Fix permissions
RUN chown -R redash /opt/redash
# Expose ports
EXPOSE 5000
EXPOSE 9001
# Startup script
CMD ["supervisord", "-c", "/opt/redash/supervisord/supervisord.conf"]

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2020, Arik Fraimovich.
Copyright (c) 2013-2016, Arik Fraimovich.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,3 +0,0 @@
The Bahrain map data used in Redash was downloaded from
https://cartographyvectors.com/map/857-bahrain-detailed-boundary in PR #6192.
* Free for personal and commercial purpose with attribution.

View File

@@ -1,80 +1,22 @@
.PHONY: compose_build up test_db create_database clean clean-all down tests lint backend-unit-tests frontend-unit-tests test build watch start redis-cli bash
NAME=redash
VERSION=`python ./manage.py version`
FULL_VERSION=$(VERSION)+b$(CIRCLE_BUILD_NUM)
BASE_VERSION=$(shell python ./manage.py version | cut -d + -f 1)
# VERSION gets evaluated every time it's referenced, therefore we need to use VERSION here instead of FULL_VERSION.
FILENAME=$(CIRCLE_ARTIFACTS)/$(NAME).$(VERSION).tar.gz
compose_build: .env
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose build
deps:
if [ -d "./rd_ui/app" ]; then npm install; fi
if [ -d "./rd_ui/app" ]; then npm run bower install; fi
if [ -d "./rd_ui/app" ]; then npm run build; fi
up:
docker compose up -d redis postgres --remove-orphans
docker compose exec -u postgres postgres psql postgres --csv \
-1tqc "SELECT table_name FROM information_schema.tables WHERE table_name = 'organizations'" 2> /dev/null \
| grep -q "organizations" || make create_database
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose up -d --build --remove-orphans
pack:
sed -ri "s/^__version__ = '([0-9.]*)'/__version__ = '$(FULL_VERSION)'/" redash/__init__.py
tar -zcv -f $(FILENAME) --exclude="optipng*" --exclude=".git*" --exclude="*.pyc" --exclude="*.pyo" --exclude="venv" --exclude="node_modules" --exclude="rd_ui/dist/bower_components" --exclude="rd_ui/app" *
test_db:
@for i in `seq 1 5`; do \
if (docker compose exec postgres sh -c 'psql -U postgres -c "select 1;"' 2>&1 > /dev/null) then break; \
else echo "postgres initializing..."; sleep 5; fi \
done
docker compose exec postgres sh -c 'psql -U postgres -c "drop database if exists tests;" && psql -U postgres -c "create database tests;"'
upload:
python bin/release_manager.py $(CIRCLE_SHA1) $(BASE_VERSION) $(FILENAME)
create_database: .env
docker compose run server create_db
clean:
docker compose down
docker compose --project-name cypress down
docker compose rm --stop --force
docker compose --project-name cypress rm --stop --force
docker image rm --force \
cypress-server:latest cypress-worker:latest cypress-scheduler:latest \
redash-server:latest redash-worker:latest redash-scheduler:latest
docker container prune --force
docker image prune --force
docker volume prune --force
clean-all: clean
docker image rm --force \
redash/redash:latest redis:7-alpine maildev/maildev:latest \
pgautoupgrade/pgautoupgrade:15-alpine3.8 pgautoupgrade/pgautoupgrade:latest
down:
docker compose down
.env:
printf "REDASH_COOKIE_SECRET=`pwgen -1s 32`\nREDASH_SECRET_KEY=`pwgen -1s 32`\n" >> .env
env: .env
format:
pre-commit run --all-files
tests:
docker compose run server tests
lint:
ruff check .
black --check . --diff
backend-unit-tests: up test_db
docker compose run --rm --name tests server tests
frontend-unit-tests:
CYPRESS_INSTALL_BINARY=0 PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 yarn --frozen-lockfile
yarn test
test: backend-unit-tests frontend-unit-tests lint
build:
yarn build
watch:
yarn watch
start:
yarn start
redis-cli:
docker compose run --rm redis redis-cli -h redis
bash:
docker compose run --rm server bash
test:
nosetests --with-coverage --cover-package=redash tests/
#grunt test

2
Procfile.dev Normal file
View File

@@ -0,0 +1,2 @@
web: ./manage.py runserver -p $PORT --host 0.0.0.0
worker: ./bin/run celery worker --app=redash.worker --beat -Qqueries,celery,scheduled_queries

2
Procfile.heroku Normal file
View File

@@ -0,0 +1,2 @@
web: ./manage.py runserver -d -r -p $PORT --host 0.0.0.0
worker: celery worker --app=redash.worker -c2 --beat -Q queries,celery,scheduled_queries

132
README.md
View File

@@ -1,120 +1,56 @@
More details about the future of re:dash : http://bit.ly/journey-first-step
---
<p align="center">
<img title="Redash" src='https://redash.io/assets/images/logo.png' width="200px"/>
<img title="re:dash" src='http://redash.io/static/old_img/redash_logo.png' width="200px"/>
</p>
<p align="center">
<img title="Build Status" src='https://circleci.com/gh/getredash/redash.png?circle-token=8a695aa5ec2cbfa89b48c275aea298318016f040'/>
</p>
[![Documentation](https://img.shields.io/badge/docs-redash.io/help-brightgreen.svg)](https://redash.io/help/)
[![GitHub Build](https://github.com/getredash/redash/actions/workflows/ci.yml/badge.svg)](https://github.com/getredash/redash/actions)
[![Join the chat at https://gitter.im/getredash/redash](https://badges.gitter.im/getredash/redash.svg)](https://gitter.im/getredash/redash?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Documentation](https://img.shields.io/badge/docs-redash.io-brightgreen.svg)](http://docs.redash.io)
Redash is designed to enable anyone, regardless of the level of technical sophistication, to harness the power of data big and small. SQL users leverage Redash to explore, query, visualize, and share data from any data sources. Their work in turn enables anybody in their organization to use the data. Every day, millions of users at thousands of organizations around the world use Redash to develop insights and make data-driven decisions.
**_re:dash_** is our take on freeing the data within our company in a way that will better fit our culture and usage patterns.
Redash features:
Prior to **_re:dash_**, we tried to use traditional BI suites and discovered a set of bloated, technically challenged and slow tools/flows. What we were looking for was a more hacker'ish way to look at data, so we built one.
1. **Browser-based**: Everything in your browser, with a shareable URL.
2. **Ease-of-use**: Become immediately productive with data without the need to master complex software.
3. **Query editor**: Quickly compose SQL and NoSQL queries with a schema browser and auto-complete.
4. **Visualization and dashboards**: Create [beautiful visualizations](https://redash.io/help/user-guide/visualizations/visualization-types) with drag and drop, and combine them into a single dashboard.
5. **Sharing**: Collaborate easily by sharing visualizations and their associated queries, enabling peer review of reports and queries.
6. **Schedule refreshes**: Automatically update your charts and dashboards at regular intervals you define.
7. **Alerts**: Define conditions and be alerted instantly when your data changes.
8. **REST API**: Everything that can be done in the UI is also available through REST API.
9. **Broad support for data sources**: Extensible data source API with native support for a long list of common databases and platforms.
**_re:dash_** was built to allow fast and easy access to billions of records, that we process and collect using Amazon Redshift ("petabyte scale data warehouse" that "speaks" PostgreSQL).
Today **_re:dash_** has support for querying multiple databases, including: Redshift, Google BigQuery, PostgreSQL, MySQL, Graphite,
Presto, Google Spreadsheets, Cloudera Impala, Hive and custom scripts.
<img src="https://raw.githubusercontent.com/getredash/website/8e820cd02c73a8ddf4f946a9d293c54fd3fb08b9/website/_assets/images/redash-anim.gif" width="80%"/>
**_re:dash_** consists of two parts:
1. **Query Editor**: think of [JS Fiddle](http://jsfiddle.net) for SQL queries. It's your way to share data in the organization in an open way, by sharing both the dataset and the query that generated it. This way everyone can peer review not only the resulting dataset but also the process that generated it. Also it's possible to fork it and generate new datasets and reach new insights.
2. **Dashboards/Visualizations**: once you have a dataset, you can create different visualizations out of it, and then combine several visualizations into a single dashboard. Currently it supports charts, pivot table and cohorts.
**_re:dash_** is a work in progress and has its rough edges and way to go to fulfill its full potential. The Query Editor part is quite solid, but the visualizations need more work to enrich them and to make them more user friendly.
## Demo
<img src="https://cloud.githubusercontent.com/assets/71468/12611424/1faf4d6a-c4f5-11e5-89b5-31efc1155d2c.gif" width="60%"/>
You can try out the demo instance: http://demo.redash.io/ (login with any Google account).
## Getting Started
* [Setting up Redash instance](https://redash.io/help/open-source/setup) (includes links to ready-made AWS/GCE images).
* [Documentation](https://redash.io/help/).
* [Setting up re:dash instance](http://redash.io/deployment/setup.html) (includes links to ready made AWS/GCE images).
* [Documentation](http://docs.redash.io).
## Supported Data Sources
Redash supports more than 35 SQL and NoSQL [data sources](https://redash.io/help/data-sources/supported-data-sources). It can also be extended to support more. Below is a list of built-in sources:
- Amazon Athena
- Amazon CloudWatch / Insights
- Amazon DynamoDB
- Amazon Redshift
- ArangoDB
- Axibase Time Series Database
- Apache Cassandra
- ClickHouse
- CockroachDB
- Couchbase
- CSV
- Databricks
- DB2 by IBM
- Dgraph
- Apache Drill
- Apache Druid
- e6data
- Eccenca Corporate Memory
- Elasticsearch
- Exasol
- Microsoft Excel
- Firebolt
- Databend
- Google Analytics
- Google BigQuery
- Google Spreadsheets
- Graphite
- Greenplum
- Apache Hive
- Apache Impala
- InfluxDB
- InfluxDBv2
- IBM Netezza Performance Server
- JIRA (JQL)
- JSON
- Apache Kylin
- OmniSciDB (Formerly MapD)
- MariaDB
- MemSQL
- Microsoft Azure Data Warehouse / Synapse
- Microsoft Azure SQL Database
- Microsoft Azure Data Explorer / Kusto
- Microsoft SQL Server
- MongoDB
- MySQL
- Oracle
- Apache Phoenix
- Apache Pinot
- PostgreSQL
- Presto
- Prometheus
- Python
- Qubole
- Rockset
- RisingWave
- Salesforce
- ScyllaDB
- Shell Scripts
- Snowflake
- SPARQL
- SQLite
- TiDB
- Tinybird
- TreasureData
- Trino
- Uptycs
- Vertica
- Yandex AppMetrrica
- Yandex Metrica
## Getting Help
* Issues: https://github.com/getredash/redash/issues
* Discussion Forum: https://github.com/getredash/redash/discussions/
* Development Discussion: https://discord.gg/tN5MdmfGBp
* Discussion Forum: https://discuss.redash.io/
* Slack: http://slack.redash.io/
* Gitter (chat): https://gitter.im/getredash/redash
## Reporting Bugs and Contributing Code
* Want to report a bug or request a feature? Please open [an issue](https://github.com/getredash/redash/issues/new).
* Want to help us build **_Redash_**? Fork the project, edit in a [dev environment](https://github.com/getredash/redash/wiki/Local-development-setup) and make a pull request. We need all the help we can get!
## Security
Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use [this PGP key](https://keybase.io/arikfr/key.asc).
* Want to help us build **_re:dash_**? Fork the project, edit in a [dev environment](http://docs.redash.io/en/latest/dev/vagrant.html), and make a pull request. We need all the help we can get!
## License
BSD-2-Clause.
See [LICENSE](https://github.com/getredash/redash/blob/master/LICENSE) file.

View File

@@ -1,5 +0,0 @@
# Security Policy
## Reporting a Vulnerability
Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use [this PGP key](https://keybase.io/arikfr/key.asc).

15
Vagrantfile vendored Normal file
View File

@@ -0,0 +1,15 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "redash/dev"
config.vm.synced_folder "./", "/opt/redash/current"
config.vm.network "forwarded_port", guest: 5000, host: 9001
config.vm.provision "shell" do |s|
s.inline = "/opt/redash/current/setup/vagrant/provision.sh"
s.privileged = false
end
end

View File

@@ -1,146 +0,0 @@
#!/bin/bash
set -e
scheduler() {
echo "Starting RQ scheduler..."
exec /app/manage.py rq scheduler
}
dev_scheduler() {
echo "Starting dev RQ scheduler..."
exec watchmedo auto-restart --directory=./redash/ --pattern=*.py --recursive -- ./manage.py rq scheduler
}
worker() {
echo "Starting RQ worker..."
export WORKERS_COUNT=${WORKERS_COUNT:-2}
export QUEUES=${QUEUES:-}
exec supervisord -c worker.conf
}
workers_healthcheck() {
WORKERS_COUNT=${WORKERS_COUNT}
echo "Checking active workers count against $WORKERS_COUNT..."
ACTIVE_WORKERS_COUNT=`echo $(rq info --url $REDASH_REDIS_URL -R | grep workers | grep -oP ^[0-9]+)`
if [ "$ACTIVE_WORKERS_COUNT" -lt "$WORKERS_COUNT" ]; then
echo "$ACTIVE_WORKERS_COUNT workers are active, Exiting"
exit 1
else
echo "$ACTIVE_WORKERS_COUNT workers are active"
exit 0
fi
}
dev_worker() {
echo "Starting dev RQ worker..."
exec watchmedo auto-restart --directory=./redash/ --pattern=*.py --recursive -- ./manage.py rq worker $QUEUES
}
server() {
# Recycle gunicorn workers every n-th request. See http://docs.gunicorn.org/en/stable/settings.html#max-requests for more details.
MAX_REQUESTS=${MAX_REQUESTS:-1000}
MAX_REQUESTS_JITTER=${MAX_REQUESTS_JITTER:-100}
TIMEOUT=${REDASH_GUNICORN_TIMEOUT:-60}
exec /usr/local/bin/gunicorn -b 0.0.0.0:5000 --name redash -w${REDASH_WEB_WORKERS:-4} redash.wsgi:app --max-requests $MAX_REQUESTS --max-requests-jitter $MAX_REQUESTS_JITTER --timeout $TIMEOUT
}
create_db() {
exec /app/manage.py database create_tables
}
help() {
echo "Redash Docker."
echo ""
echo "Usage:"
echo ""
echo "server -- start Redash server (with gunicorn)"
echo "worker -- start a single RQ worker"
echo "dev_worker -- start a single RQ worker with code reloading"
echo "scheduler -- start an rq-scheduler instance"
echo "dev_scheduler -- start an rq-scheduler instance with code reloading"
echo ""
echo "shell -- open shell"
echo "dev_server -- start Flask development server with debugger and auto reload"
echo "debug -- start Flask development server with remote debugger via debugpy"
echo "create_db -- create database tables"
echo "manage -- CLI to manage redash"
echo "tests -- run tests"
}
tests() {
export REDASH_DATABASE_URL="postgresql://postgres@postgres/tests"
if [ $# -eq 0 ]; then
TEST_ARGS=tests/
else
TEST_ARGS=$@
fi
exec pytest $TEST_ARGS
}
case "$1" in
worker)
shift
worker
;;
workers_healthcheck)
shift
workers_healthcheck
;;
server)
shift
server
;;
scheduler)
shift
scheduler
;;
dev_scheduler)
shift
dev_scheduler
;;
dev_worker)
shift
dev_worker
;;
celery_healthcheck)
shift
echo "DEPRECATED: Celery has been replaced with RQ and now performs healthchecks autonomously as part of the 'worker' entrypoint."
;;
dev_server)
export FLASK_DEBUG=1
exec /app/manage.py runserver --debugger --reload -h 0.0.0.0
;;
debug)
export FLASK_DEBUG=1
export REMOTE_DEBUG=1
exec /app/manage.py runserver --debugger --no-reload -h 0.0.0.0
;;
shell)
exec /app/manage.py shell
;;
create_db)
create_db
;;
manage)
shift
exec /app/manage.py $*
;;
tests)
shift
tests $@
;;
help)
shift
help
;;
*)
exec "$@"
;;
esac

View File

@@ -1,46 +0,0 @@
#!/bin/env python3
import re
import subprocess
import sys
def get_change_log(previous_sha):
args = [
"git",
"--no-pager",
"log",
"--merges",
"--grep",
"Merge pull request",
'--pretty=format:"%h|%s|%b|%p"',
"master...{}".format(previous_sha),
]
log = subprocess.check_output(args)
changes = []
for line in log.split("\n"):
try:
sha, subject, body, parents = line[1:-1].split("|")
except ValueError:
continue
try:
pull_request = re.match(r"Merge pull request #(\d+)", subject).groups()[0]
pull_request = " #{}".format(pull_request)
except Exception:
pull_request = ""
author = subprocess.check_output(["git", "log", "-1", '--pretty=format:"%an"', parents.split(" ")[-1]])[1:-1]
changes.append("{}{}: {} ({})".format(sha, pull_request, body.strip(), author))
return changes
if __name__ == "__main__":
previous_sha = sys.argv[1]
changes = get_change_log(previous_sha)
for change in changes:
print(change)

18
bin/pre_compile Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Heroku pre_compile script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
pushd $DIR/..
# heroku requires cffi to be in requirements.txt in order for libffi to be installed.
# https://github.com/heroku/heroku-buildpack-python/blob/master/bin/steps/cryptography
# to avoid making it a requirement for other build systems, we'll inject it now
# into the requirements.txt file
# Remove Heroku unsupported Python packages:
grep -v -E "^(pymssql|thrift|sasl|pyhive)" requirements_all_ds.txt >> requirements.txt
# make the heroku Procfile the active one
cp Procfile.heroku Procfile
popd

View File

@@ -1,42 +1,35 @@
#!/usr/bin/env python3
import os
import sys
import json
import re
import subprocess
import sys
from urllib.parse import urlparse
import requests
import simplejson
github_token = os.environ["GITHUB_TOKEN"]
auth = (github_token, "x-oauth-basic")
repo = "getredash/redash"
github_token = os.environ['GITHUB_TOKEN']
auth = (github_token, 'x-oauth-basic')
repo = 'getredash/redash'
def _github_request(method, path, params=None, headers={}):
if urlparse(path).hostname != "api.github.com":
if not path.startswith('https://api.github.com'):
url = "https://api.github.com/{}".format(path)
else:
url = path
if params is not None:
params = simplejson.dumps(params)
params = json.dumps(params)
response = requests.request(method, url, data=params, auth=auth)
return response
def exception_from_error(message, response):
return Exception("({}) {}: {}".format(response.status_code, message, response.json().get("message", "?")))
return Exception("({}) {}: {}".format(response.status_code, message, response.json().get('message', '?')))
def rc_tag_name(version):
return "v{}-rc".format(version)
def get_rc_release(version):
tag = rc_tag_name(version)
response = _github_request("get", "repos/{}/releases/tags/{}".format(repo, tag))
response = _github_request('get', 'repos/{}/releases/tags/{}'.format(repo, tag))
if response.status_code == 404:
return None
@@ -45,101 +38,84 @@ def get_rc_release(version):
raise exception_from_error("Unknown error while looking RC release: ", response)
def create_release(version, commit_sha):
tag = rc_tag_name(version)
params = {
"tag_name": tag,
"name": "{} - RC".format(version),
"target_commitish": commit_sha,
"prerelease": True,
'tag_name': tag,
'name': "{} - RC".format(version),
'target_commitish': commit_sha,
'prerelease': True
}
response = _github_request("post", "repos/{}/releases".format(repo), params)
response = _github_request('post', 'repos/{}/releases'.format(repo), params)
if response.status_code != 201:
raise exception_from_error("Failed creating new release", response)
return response.json()
def upload_asset(release, filepath):
upload_url = release["upload_url"].replace("{?name,label}", "")
filename = filepath.split("/")[-1]
upload_url = release['upload_url'].replace('{?name,label}', '')
filename = filepath.split('/')[-1]
with open(filepath) as file_content:
headers = {"Content-Type": "application/gzip"}
response = requests.post(
upload_url, file_content, params={"name": filename}, headers=headers, auth=auth, verify=False
)
headers = {'Content-Type': 'application/gzip'}
response = requests.post(upload_url, file_content, params={'name': filename}, headers=headers, auth=auth, verify=False)
if response.status_code != 201: # not 200/201/...
raise exception_from_error("Failed uploading asset", response)
raise exception_from_error('Failed uploading asset', response)
return response
def remove_previous_builds(release):
for asset in release["assets"]:
response = _github_request("delete", asset["url"])
for asset in release['assets']:
response = _github_request('delete', asset['url'])
if response.status_code != 204:
raise exception_from_error("Failed deleting asset", response)
def get_changelog(commit_sha):
latest_release = _github_request("get", "repos/{}/releases/latest".format(repo))
latest_release = _github_request('get', 'repos/{}/releases/latest'.format(repo))
if latest_release.status_code != 200:
raise exception_from_error("Failed getting latest release", latest_release)
raise exception_from_error('Failed getting latest release', latest_release)
latest_release = latest_release.json()
previous_sha = latest_release["target_commitish"]
previous_sha = latest_release['target_commitish']
args = [
"git",
"--no-pager",
"log",
"--merges",
"--grep",
"Merge pull request",
'--pretty=format:"%h|%s|%b|%p"',
"{}...{}".format(previous_sha, commit_sha),
]
args = ['git', '--no-pager', 'log', '--merges', '--grep', 'Merge pull request', '--pretty=format:"%h|%s|%b|%p"', '{}...{}'.format(previous_sha, commit_sha)]
log = subprocess.check_output(args)
changes = ["Changes since {}:".format(latest_release["name"])]
changes = ["Changes since {}:".format(latest_release['name'])]
for line in log.split("\n"):
for line in log.split('\n'):
try:
sha, subject, body, parents = line[1:-1].split("|")
sha, subject, body, parents = line[1:-1].split('|')
except ValueError:
continue
try:
pull_request = re.match(r"Merge pull request #(\d+)", subject).groups()[0]
pull_request = re.match("Merge pull request #(\d+)", subject).groups()[0]
pull_request = " #{}".format(pull_request)
except Exception:
except Exception, ex:
pull_request = ""
author = subprocess.check_output(["git", "log", "-1", '--pretty=format:"%an"', parents.split(" ")[-1]])[1:-1]
author = subprocess.check_output(['git', 'log', '-1', '--pretty=format:"%an"', parents.split(' ')[-1]])[1:-1]
changes.append("{}{}: {} ({})".format(sha, pull_request, body.strip(), author))
return "\n".join(changes)
def update_release_commit_sha(release, commit_sha):
params = {
"target_commitish": commit_sha,
'target_commitish': commit_sha,
}
response = _github_request("patch", "repos/{}/releases/{}".format(repo, release["id"]), params)
response = _github_request('patch', 'repos/{}/releases/{}'.format(repo, release['id']), params)
if response.status_code != 200:
raise exception_from_error("Failed updating commit sha for existing release", response)
return response.json()
def update_release(version, build_filepath, commit_sha):
try:
release = get_rc_release(version)
@@ -148,22 +124,21 @@ def update_release(version, build_filepath, commit_sha):
else:
release = create_release(version, commit_sha)
print("Using release id: {}".format(release["id"]))
print "Using release id: {}".format(release['id'])
remove_previous_builds(release)
response = upload_asset(release, build_filepath)
changelog = get_changelog(commit_sha)
response = _github_request("patch", release["url"], {"body": changelog})
response = _github_request('patch', release['url'], {'body': changelog})
if response.status_code != 200:
raise exception_from_error("Failed updating release description", response)
except Exception as ex:
print(ex)
except Exception, ex:
print ex
if __name__ == "__main__":
if __name__ == '__main__':
commit_sha = sys.argv[1]
version = sys.argv[2]
filepath = sys.argv[3]

21
bin/vagrant_ctl.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
set -e
help() {
echo "Usage: "
echo "`basename "$0"` {start, test}"
}
case "$1" in
start)
vagrant up
vagrant ssh -c "cd /opt/redash/current; bin/run honcho start -f Procfile.dev;"
;;
test)
vagrant up
vagrant ssh -c "cd /opt/redash/current; make test"
;;
*)
help
;;
esac

47
bower.json Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "redash",
"version": "0.11.1",
"dependencies": {
"angular": "1.2.18",
"angular-resource": "1.2.18",
"angular-route": "1.2.18",
"angular-growl": "0.4.0",
"json3": "3.2.4",
"jquery": "1.9.1",
"bootstrap": "3.3.6",
"es5-shim": "2.0.8",
"angular-moment": "0.10.3",
"moment": "~2.8.0",
"codemirror": "4.8.0",
"underscore": "1.5.1",
"pivottable": "2.0.2",
"cornelius": "https://github.com/restorando/cornelius.git",
"gridster": "0.2.0",
"mousetrap": "~1.4.6",
"jquery-ui": "~1.10.4",
"underscore.string": "~2.3.3",
"marked": "~0.3.2",
"pace": "~0.5.1",
"font-awesome": "~4.2.0",
"mustache": "~1.0.0",
"canvg": "gabelerner/canvg",
"angular-ui-bootstrap-bower": "~0.12.1",
"leaflet": "~0.7.3",
"angular-base64-upload": "~0.1.11",
"angular-ui-select": "~0.13.2",
"angular-bootstrap-show-errors": "~2.3.0",
"angular-sanitize": "1.2.18",
"d3": "3.5.6",
"angular-ui-sortable": "~0.13.4",
"angular-resizable": "^1.2.0",
"material-design-iconic-font": "^2.2.0",
"plotly.js": "^1.9.0"
},
"devDependencies": {
"angular-mocks": "1.2.18",
"angular-scenario": "1.2.18"
},
"resolutions": {
"angular": "1.2.18"
}
}

39
circle.yml Normal file
View File

@@ -0,0 +1,39 @@
machine:
services:
- docker
node:
version:
0.12.4
python:
version:
2.7.3
dependencies:
pre:
- pip install -r requirements_dev.txt
- pip install -r requirements.txt
- pip install pymongo==3.2.1
- make deps
cache_directories:
- node_modules/
- rd_ui/app/bower_components/
test:
override:
- nosetests --with-xunit --xunit-file=$CIRCLE_TEST_REPORTS/junit.xml --with-coverage --cover-package=redash tests/
deployment:
github_and_docker:
branch: [master, /release_.*/]
commands:
- make pack
- make upload
- echo "rd_ui/app" >> .dockerignore
- docker pull redash/redash:latest
- docker build -t redash/redash:$(./manage.py version | sed -e "s/\+/./") .
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
- docker push redash/redash:$(./manage.py version | sed -e "s/\+/./")
notify:
webhooks:
- url: https://webhooks.gitter.im/e/895d09c3165a0913ac2f
general:
branches:
ignore:
- gh-pages

View File

@@ -1,29 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"exclude": ["@babel/plugin-transform-async-to-generator", "@babel/plugin-transform-arrow-functions"],
"corejs": "2",
"useBuiltIns": "usage"
}
],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-object-assign",
[
"babel-plugin-transform-builtin-extend",
{
"globals": ["Error"]
}
]
],
"env": {
"test": {
"plugins": ["istanbul"]
}
}
}

View File

@@ -1,4 +0,0 @@
build/*.js
dist
config/*.js
client/dist

View File

@@ -1,71 +0,0 @@
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
extends: [
"react-app",
"plugin:compat/recommended",
"prettier",
"plugin:jsx-a11y/recommended",
// Remove any typescript-eslint rules that would conflict with prettier
"prettier/@typescript-eslint",
],
plugins: ["jest", "compat", "no-only-tests", "@typescript-eslint", "jsx-a11y"],
settings: {
"import/resolver": "webpack",
},
env: {
browser: true,
node: true,
},
rules: {
// allow debugger during development
"no-debugger": process.env.NODE_ENV === "production" ? 2 : 0,
"jsx-a11y/anchor-is-valid": [
// TMP
"off",
{
components: ["Link"],
aspects: ["noHref", "invalidHref", "preferButton"],
},
],
"jsx-a11y/no-redundant-roles": "error",
"jsx-a11y/no-autofocus": "off",
"jsx-a11y/click-events-have-key-events": "off", // TMP
"jsx-a11y/no-static-element-interactions": "off", // TMP
"jsx-a11y/no-noninteractive-element-interactions": "off", // TMP
"no-console": ["warn", { allow: ["warn", "error"] }],
"no-restricted-imports": [
"error",
{
paths: [
{
name: "antd",
message: "Please use 'import XXX from antd/lib/XXX' import instead.",
},
{
name: "antd/lib",
message: "Please use 'import XXX from antd/lib/XXX' import instead.",
},
],
},
],
},
overrides: [
{
// Only run typescript-eslint on TS files
files: ["*.ts", "*.tsx", ".*.ts", ".*.tsx"],
extends: ["plugin:@typescript-eslint/recommended"],
rules: {
// Do not require functions (especially react components) to have explicit returns
"@typescript-eslint/explicit-function-return-type": "off",
// Do not require to type every import from a JS file to speed up development
"@typescript-eslint/no-explicit-any": "off",
// Do not complain about useless contructors in declaration files
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "error",
// Many API fields and generated types use camelcase
"@typescript-eslint/camelcase": "off",
},
},
],
};

1
client/.gitignore vendored
View File

@@ -1 +0,0 @@
dist

View File

@@ -1,10 +0,0 @@
module.exports = {
extends: ["plugin:jest/recommended"],
plugins: ["jest"],
env: {
"jest/globals": true,
},
rules: {
"jest/no-focused-tests": "off",
},
};

View File

@@ -1,4 +0,0 @@
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });

View File

@@ -1,5 +0,0 @@
import MockDate from "mockdate";
const date = new Date("2000-01-01T02:00:00.000");
MockDate.set(date);

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="630" height="630" viewBox="0 0 630 630" version="1.1">
<g transform="translate(-56.611934,-184.36221)">
<path fill="#a7a7a7" d="m 58.467329,810.92426 c 0,-10.37237 6.53079,-28.55017 15.29935,-42.58418 9.70782,-15.53729 28.965401,-35.11964 51.655121,-52.52627 7.21357,-5.53395 6.57284,-5.08564 22.23877,-15.56023 20.2393,-13.53245 55.34935,-32.58361 79.80676,-43.30416 19.72995,-8.64834 57.2268,-21.58721 62.55974,-21.58721 0.76988,0 3.09659,-0.67892 5.17046,-1.50872 7.3197,-2.92876 12.5713,-16.1286 13.89202,-34.91737 l 0.64689,-9.20257 -8.38455,-10.04931 c -7.66622,-9.18836 -11.59308,-14.62897 -20.80286,-28.82203 -9.85543,-15.1881 -22.91997,-47.26171 -24.69185,-60.61889 -0.56037,-4.22429 -1.0976,-5.21546 -3.27999,-6.05157 -10.15146,-3.88918 -15.7489,-9.08881 -20.96084,-19.47118 -6.6162,-13.17971 -8.62087,-36.5618 -4.2711,-49.81738 2.29242,-6.98599 4.4873,-10.89589 8.72413,-15.54098 2.11744,-2.32146 2.22102,-2.9999 1.45041,-9.5 -2.58899,-21.83821 -3.34954,-41.36055 -2.18394,-56.05862 3.87891,-48.91259 20.17112,-81.47548 50.89033,-101.71339 16.68129,-10.98968 34.4196,-16.74492 62.2113,-20.1846 32.20647,-3.98609 68.82401,0.75436 93.8318,12.14731 14.67849,6.68717 28.98155,17.91433 38.99893,30.61215 19.81832,25.12131 29.57328,66.42856 26.24603,111.13853 -0.69821,9.38224 -1.63714,20.17477 -2.08651,23.9834 -0.81425,6.90129 -0.80559,6.93815 2.55469,10.86388 7.03777,8.22205 10.02312,18.44949 9.84447,33.72599 -0.27308,23.35114 -10.37432,43.49379 -24.44339,48.74202 l -5.34465,1.99373 -1.18738,6.3748 c -4.9831,26.75313 -22.71761,61.14702 -45.76986,88.76506 l -7.88572,9.44759 0.64805,9.21931 c 1.18682,16.88381 6.49256,31.6953 12.30203,34.34227 1.23595,0.56314 6.42637,1.99946 11.53427,3.19182 35.45428,8.27628 97.76078,37.16683 137.59386,63.80012 15.66594,10.47459 15.02521,10.02628 22.23877,15.56023 22.46534,17.23449 41.43241,36.56563 52.11597,53.1163 7.31528,11.33263 13.49882,27.98884 14.54335,39.17447 l 0.58435,6.25763 -313.14461,0 -313.144601,0 0,-3.43795 z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Some files were not shown because too many files have changed in this diff Show More