diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..ce90f5da --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + cooldown: + default-days: 7 + groups: + github-actions: + patterns: ["*"] + commit-message: + prefix: "CI" diff --git a/.github/workflows/compose-validation.yml b/.github/workflows/compose-validation.yml index 23297007..34b536bb 100644 --- a/.github/workflows/compose-validation.yml +++ b/.github/workflows/compose-validation.yml @@ -4,15 +4,9 @@ on: push: branches: - main - paths: - - 'services/**' - - '.github/workflows/compose-validation.yml' pull_request: branches: - main - paths: - - 'services/**' - - '.github/workflows/compose-validation.yml' permissions: contents: read @@ -23,24 +17,50 @@ concurrency: jobs: validate: + name: Compose files runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Clone this repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false # Some stacks require the user to set their own secrets and stop with # "required variable X is missing". Supply a dummy value for those and - # retry, so that the rest of the file is still checked. + # retry, so that the rest of the file is still checked. The template + # leaves SERVICE and IMAGE_URL empty, so it starts with dummy values for + # both. A variable that compose.yaml uses but .env does not define + # ("The X variable is not set") is an error, and so is a required + # variable that .env does not list or a Serve configuration that is not + # valid JSON. - name: Run docker compose config run: | + docker compose version status=0 - for dir in services/*/; do + for dir in services/*/ templates/service-template/; do vars=() + if [ "$dir" = templates/service-template/ ]; then + vars=(SERVICE IMAGE_URL) + fi ok=0 - for attempt in $(seq 1 30); do + for _ in $(seq 1 30); do if out=$(cd "$dir" && env "${vars[@]/%/=dummy}" docker compose config --quiet 2>&1); then ok=1 + unset_vars=$(sed -nE 's/.*The \\?"([A-Za-z0-9_]+)\\?" variable is not set.*/\1/p' <<<"$out" | sort -u | paste -sd' ' -) + if [ -n "$unset_vars" ]; then + echo "::error file=${dir}compose.yaml::Used in compose.yaml but not defined in ${dir}.env: ${unset_vars}" + status=1 + fi + for v in "${vars[@]}"; do + grep -qE "^${v}=" "${dir}.env" || { echo "::error file=${dir}compose.yaml::${v} is required but not listed in ${dir}.env"; status=1; } + done + if ! (cd "$dir" && env "${vars[@]/%/=dummy}" docker compose config --format json 2>/dev/null \ + | jq -r '(.configs // {}) | to_entries[] | select(.key | startswith("ts-serve")) | .value.content' \ + | jq empty); then + echo "::error file=${dir}compose.yaml::The Tailscale Serve configuration is not valid JSON" + status=1 + fi break fi missing=$(grep -oE 'required variable [A-Za-z0-9_]+' <<<"$out" | awk '{print $3}' | sort -u | grep -vxFf <(printf '%s\n' "${vars[@]}") || true) @@ -51,7 +71,8 @@ jobs: ok=2 break fi - vars+=($missing) + mapfile -t new <<<"$missing" + vars+=("${new[@]}") done if [ "$ok" = 0 ]; then echo "::error file=${dir}compose.yaml::too many required variables in ${dir}" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index b0a9ed7e..f8e36c6c 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -4,21 +4,9 @@ on: push: branches: - main - paths-ignore: - # - 'README.md' - - 'LICENSE' - - '.gitignore' - - '.gitattributes' - - '.editorconfig' pull_request: branches: - main - paths-ignore: - # - 'README.md' - - 'LICENSE' - - '.gitignore' - - '.gitattributes' - - '.editorconfig' permissions: contents: read @@ -34,6 +22,20 @@ jobs: steps: - name: Clone this repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + # Dependabot bumps the action's SHA but not the version input. Fail until + # both name the same rumdl version. + - name: Check that the rumdl version matches the pinned action + run: | + f=.github/workflows/linting.yml + action=$(grep -oE 'rvben/rumdl@[0-9a-f]{40} # v[0-9.]+' "$f" | sed 's/.*# v//') + input=$(grep -oE 'version: "[0-9.]+"' "$f" | grep -oE '[0-9.]+') + if [ -z "$action" ] || [ "$action" != "$input" ]; then + echo "::error file=$f::rvben/rumdl is pinned to v${action:-?} but installs rumdl ${input:-?}. Set version: \"${action}\"." + exit 1 + fi - name: Lint Markdown uses: rvben/rumdl@9c4cc2a2ebe176de68e1788106e25af8a9bd3899 # v0.2.78 diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml new file mode 100644 index 00000000..cf2e56aa --- /dev/null +++ b/.github/workflows/workflow-lint.yml @@ -0,0 +1,35 @@ +name: Lint workflows +on: + pull_request: + branches: [main] + paths: ['.github/**'] + push: + branches: [main] + paths: ['.github/**'] +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} +jobs: + workflows: + name: Workflow lint + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: actionlint + run: | + f=actionlint_1.7.12_linux_amd64.tar.gz + curl -sSfLO "https://github.com/rhysd/actionlint/releases/download/v1.7.12/$f" + echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $f" | sha256sum -c - + tar xzf "$f" actionlint + ./actionlint -color + - name: zizmor + uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4 + with: + advanced-security: false + annotations: true + version: "1.30.1" diff --git a/services/formbricks/.env b/services/formbricks/.env index cee55dc3..711062ee 100644 --- a/services/formbricks/.env +++ b/services/formbricks/.env @@ -67,7 +67,7 @@ LOG_LEVEL="info" # Enterprise License Key (More info at: https://formbricks.com/docs/self-hosting/license) # Required to access Enterprise-only features -# ENTERPRISE_LICENSE_KEY="" +ENTERPRISE_LICENSE_KEY="" ############################################# OPTIONAL (EMAIL CONFIGURATION) ############################################# @@ -101,31 +101,31 @@ EMAIL_AUTH_DISABLED="0" INVITE_DISABLED="0" # Set the below if you want to ship JS & CSS files from a complete URL instead of the current domain -# ASSET_PREFIX_URL="" +ASSET_PREFIX_URL="" # Set the below to your Unsplash API Key for their Survey Backgrounds -# UNSPLASH_ACCESS_KEY="" +UNSPLASH_ACCESS_KEY="" # The SENTRY_DSN is used for error tracking and performance monitoring with Sentry. -# SENTRY_DSN="" +SENTRY_DSN="" # It's used for authentication when uploading source maps to Sentry, to make errors more readable. -# SENTRY_AUTH_TOKEN="" +SENTRY_AUTH_TOKEN="" # The SENTRY_ENVIRONMENT is used to identify the environment in Sentry. -# SENTRY_ENVIRONMENT="" +SENTRY_ENVIRONMENT="" ################################################### OPTIONAL (STORAGE) ################################################### # Set S3 Storage configuration (required for the file upload in serverless environments like Vercel) -# S3_ACCESS_KEY="" -# S3_SECRET_KEY="" -# S3_REGION="" -# S3_BUCKET_NAME="" +S3_ACCESS_KEY="" +S3_SECRET_KEY="" +S3_REGION="" +S3_BUCKET_NAME="" # Set a third party S3 compatible storage service endpoint like StorJ leave empty if you use Amazon S3 -# S3_ENDPOINT_URL="" +S3_ENDPOINT_URL="" # Force path style for S3 compatible storage (0 for disabled, 1 for enabled) S3_FORCE_PATH_STYLE="0" @@ -133,67 +133,68 @@ S3_FORCE_PATH_STYLE="0" ############################################# OPTIONAL (OAUTH CONFIGURATION) ############################################# # Set the below from Cloudflare Turnstile if you want to enable turnstile in signups -# TURNSTILE_SITE_KEY="" -# TURNSTILE_SECRET_KEY="" +TURNSTILE_SITE_KEY="" +TURNSTILE_SECRET_KEY="" # Set the below keys to enable recaptcha V3 for survey responses bot protection(only available in the Enterprise Edition) -# RECAPTCHA_SITE_KEY="" -# RECAPTCHA_SECRET_KEY="" +RECAPTCHA_SITE_KEY="" +RECAPTCHA_SECRET_KEY="" # Set the below from GitHub if you want to enable GitHub OAuth -# GITHUB_ID="" -# GITHUB_SECRET="" +GITHUB_ID="" +GITHUB_SECRET="" # Set the below from Google if you want to enable Google OAuth -# GOOGLE_CLIENT_ID="" -# GOOGLE_CLIENT_SECRET="" +GOOGLE_CLIENT_ID="" +GOOGLE_CLIENT_SECRET="" # Set the below from Azure Active Directory Login if you want to enable Azure AD OAuth -# AZUREAD_CLIENT_ID="" -# AZUREAD_CLIENT_SECRET="" -# AZUREAD_TENANT_ID="" +AZUREAD_CLIENT_ID="" +AZUREAD_CLIENT_SECRET="" +AZUREAD_TENANT_ID="" # Set the below to OpenID Connect Provider if you want to enable OIDC -# OIDC_CLIENT_ID="" -# OIDC_CLIENT_SECRET="" -# OIDC_ISSUER="" -# OIDC_DISPLAY_NAME="" -# OIDC_SIGNING_ALGORITHM="" +OIDC_CLIENT_ID="" +OIDC_CLIENT_SECRET="" +OIDC_ISSUER="" +OIDC_DISPLAY_NAME="" +OIDC_SIGNING_ALGORITHM="" # Set the below to SAML Provider if you want to enable SAML -# SAML_DATABASE_URL="postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/formbricks-saml?sslmode=disable" +# Example: SAML_DATABASE_URL="postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/formbricks-saml?sslmode=disable" +SAML_DATABASE_URL= ########################################## OPTIONAL (THIRD PARTY INTEGRATIONS) ########################################### # Oauth credentials for Notion Integration -# NOTION_OAUTH_CLIENT_ID="" -# NOTION_OAUTH_CLIENT_SECRET="" +NOTION_OAUTH_CLIENT_ID="" +NOTION_OAUTH_CLIENT_SECRET="" # Oauth credentials for Google Sheet Integration -# GOOGLE_SHEETS_CLIENT_ID="" -# GOOGLE_SHEETS_CLIENT_SECRET="" -# GOOGLE_SHEETS_REDIRECT_URL="" +GOOGLE_SHEETS_CLIENT_ID="" +GOOGLE_SHEETS_CLIENT_SECRET="" +GOOGLE_SHEETS_REDIRECT_URL="" # Oauth credentials for Airtable Integration -# AIRTABLE_CLIENT_ID="" +AIRTABLE_CLIENT_ID="" # Oauth credentials for Slack Integration -# SLACK_CLIENT_ID="" -# SLACK_CLIENT_SECRET="" +SLACK_CLIENT_ID="" +SLACK_CLIENT_SECRET="" ############################################### OPTIONAL (LEGAL INFORMATION) ################################################ # Set the below to have your own Privacy Page URL on auth & link survey page -# PRIVACY_URL="" +PRIVACY_URL="" # Set the below to have your own Terms Page URL on auth & link survey page -# TERMS_URL="" +TERMS_URL="" # Set the below to have your own Imprint Page URL on auth & link survey page -# IMPRINT_URL="" +IMPRINT_URL="" # Set the below to have your own Address on email footer -# IMPRINT_ADDRESS="" +IMPRINT_ADDRESS="" ########################################## OPTIONAL (SERVER CONFIGURATION) ########################################### @@ -218,7 +219,7 @@ AUTH_SKIP_INVITE_FOR_SSO="0" # Set the below to automatically assign new users to a specific team, insert an existing team id # (Role Management is an Enterprise feature) -# AUTH_SSO_DEFAULT_TEAM_ID="" +AUTH_SSO_DEFAULT_TEAM_ID="" # Configure the minimum role for user management from UI(owner, manager, disabled) USER_MANAGEMENT_MINIMUM_ROLE="manager"