├── .dockerignore ├── .github ├── renovate.json └── workflows │ ├── backend_build_prod_ecr.yml │ ├── backend_docker_release.yml │ ├── backend_release.yml │ ├── backend_test.yml │ ├── cli_release.yml │ ├── cli_release_multiarch.yml │ ├── cli_test.yml │ ├── cli_test_e2e.yml │ ├── dgctl_release.yml │ ├── drift_deploy.yml │ ├── ee_backend_docker_release.yml │ ├── ee_backend_docker_release_fips.yml │ ├── ee_backend_test.yml │ ├── ee_cli_release.yml │ ├── ee_cli_release_fips.yml │ ├── ee_cli_release_multiarch.yml │ ├── ee_cli_test.yml │ ├── ee_tasks_release.yml │ ├── latest_tag.yml │ ├── libs_test.yml │ ├── misc_top_issues.yml │ ├── next_deploy.yml │ ├── next_test.yml │ ├── pro-deploy.yml │ ├── tasks_release.yml │ └── tasks_run_test.yml ├── .gitignore ├── CONTRIBUTING.md ├── Dockerfile_backend ├── Dockerfile_backend_ee ├── Dockerfile_drift ├── Dockerfile_next ├── Dockerfile_tasks ├── LICENSE ├── README.md ├── action.yml ├── backend ├── .dockerignore ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── atlas.hcl ├── bootstrap │ └── main.go ├── ci_backends │ ├── ci_backends.go │ ├── github_actions.go │ ├── jenkins.go │ └── provider.go ├── config │ ├── config.go │ └── envgetters.go ├── controllers │ ├── activity.go │ ├── cache.go │ ├── connections.go │ ├── dashboard.go │ ├── github.go │ ├── github_api.go │ ├── github_test.go │ ├── helpers.go │ ├── internal_users.go │ ├── jobs.go │ ├── locking.go │ ├── orgs.go │ ├── policies.go │ ├── policies_api.go │ ├── projects.go │ ├── projects_test.go │ ├── repos.go │ └── runs.go ├── docker-compose.yml ├── go.mod ├── go.sum ├── hooks │ └── hooks.go ├── locking │ └── backend_locking.go ├── main.go ├── middleware │ ├── basic.go │ ├── headers.go │ ├── jwt.go │ ├── middleware.go │ ├── noop.go │ └── webhook.go ├── migrations │ ├── 20231227132525.sql │ ├── 20240115170600.sql │ ├── 20240116123649.sql │ ├── 20240125121106.sql │ ├── 20240125181812.sql │ ├── 20240301211741.sql │ ├── 20240328182453.sql │ ├── 20240329100957.sql │ ├── 20240329114422.sql │ ├── 20240402110915.sql │ ├── 20240403155357_drop_dup_idx.sql │ ├── 20240403155456.sql │ ├── 20240404160724.sql │ ├── 20240404161121.sql │ ├── 20240404161723.sql │ ├── 20240404165910.sql │ ├── 20240405150942.sql │ ├── 20240405160110.sql │ ├── 20240409161739.sql │ ├── 20240510162721.sql │ ├── 20240518182629.sql │ ├── 20240524110010.sql │ ├── 20240527112209.sql │ ├── 20240530074832.sql │ ├── 20240703121051.sql │ ├── 20240704192835.sql │ ├── 20240705144450.sql │ ├── 20240709165155.sql │ ├── 20240729155442.sql │ ├── 20240729155926.sql │ ├── 20240729160028.sql │ ├── 20241107162605.sql │ ├── 20241107163722.sql │ ├── 20241107172343.sql │ ├── 20241114202249.sql │ ├── 20241229112312.sql │ ├── 20250220084846.sql │ ├── 20250220172054.sql │ ├── 20250220172321.sql │ ├── 20250220173053.sql │ ├── 20250220173439.sql │ ├── 20250221044813.sql │ ├── 20250224152926.sql │ ├── 20250226185150.sql │ ├── 20250302190926.sql │ ├── 20250325115901.sql │ ├── 20250325134924.sql │ ├── 20250416152705.sql │ ├── 20250512172515.sql │ ├── 20250512213729.sql │ └── atlas.sum ├── models │ ├── artefact.go │ ├── cache.go │ ├── github.go │ ├── locking.go │ ├── orgs.go │ ├── policies.go │ ├── runs.go │ ├── scheduler.go │ ├── scheduler_test.go │ ├── setup.go │ ├── storage.go │ ├── storage_dashboard.go │ ├── storage_test.go │ └── user.go ├── queries │ └── queries.go ├── scripts │ ├── curl_bootstrap.sh │ └── entrypoint.sh ├── segment │ └── segment.go ├── services │ ├── auth.go │ ├── messages.go │ ├── scheduler.go │ └── spec.go ├── sql │ └── migration_25_08_2023.sql ├── tasks │ ├── .gitignore │ ├── runs.go │ ├── runs_test.go │ └── tasks.go ├── templates │ ├── github_repos.tmpl │ ├── github_setup.tmpl │ ├── github_success.tmpl │ ├── home.tmpl │ ├── index.tmpl │ ├── static │ │ ├── css │ │ │ ├── bootstrap.min.css │ │ │ ├── main.css │ │ │ ├── prism.dev.css │ │ │ ├── prism.min.css │ │ │ └── tf.css │ │ ├── js │ │ │ ├── bootstrap.bundle.min.js │ │ │ ├── prism-live-javascript.js │ │ │ ├── prism-live.js │ │ │ ├── prism.dev.js │ │ │ └── prism.min.js │ │ └── prism-live.css │ └── top.tmpl ├── tools.go ├── utils │ ├── ai.go │ ├── allowlist.go │ ├── allowlist_test.go │ ├── batch_utils.go │ ├── bitbucket.go │ ├── crypt.go │ ├── github.go │ ├── github_test.go │ ├── gitlab.go │ ├── gitshell.go │ ├── graphs.go │ ├── graphs_test.go │ ├── log.go │ └── pr_comment.go └── version.txt ├── cli ├── .gitignore ├── cmd │ └── digger │ │ ├── default.go │ │ ├── main.go │ │ ├── main_test.go │ │ ├── root.go │ │ └── run_spec.go ├── dockerfiles │ ├── branch │ │ └── Dockerfile │ └── release │ │ └── Dockerfile ├── go.mod ├── go.sum └── pkg │ ├── core │ └── drift │ │ └── drift.go │ ├── digger │ ├── digger.go │ ├── digger_test.go │ ├── io.go │ └── isNonEmptyPlan.txt │ ├── drift │ ├── Provider.go │ ├── slack.go │ └── slack_test.go │ ├── github │ ├── github.go │ └── models │ │ └── models.go │ ├── integration │ └── integration_test.go │ ├── spec │ ├── manual.go │ └── spec.go │ ├── usage │ ├── usage.go │ └── usage_test.go │ └── utils │ ├── commands.go │ ├── io.go │ ├── strings.go │ └── version.go ├── cli_e2e ├── aws_dynamodb_test.go ├── go.mod ├── go.sum └── plan_storage_test.go ├── dgctl ├── .gitignore ├── cmd │ ├── exec.go │ ├── root.go │ └── validate.go ├── dgctl.json ├── go.mod ├── go.sum ├── main.go └── utils │ └── gitio.go ├── docs ├── ce │ ├── azure-specific │ │ ├── azure-devops-locking-connection-methods.mdx │ │ └── azure.mdx │ ├── cloud-providers │ │ ├── authenticating-with-oidc-on-aws.mdx │ │ ├── aws.mdx │ │ └── setting-up-separate-mgmt-account.mdx │ ├── features │ │ ├── commentops.mdx │ │ ├── concurrency.mdx │ │ ├── opa-policies.mdx │ │ ├── plan-persistence.mdx │ │ ├── plan-preview.mdx │ │ ├── pr-level-locks.mdx │ │ └── private-runners.mdx │ ├── gcp │ │ ├── federated-oidc-access.mdx │ │ ├── setting-up-gcp-+-gh-actions.mdx │ │ └── using-gcp-bucket-for-locks.mdx │ ├── getting-started │ │ ├── azure-devops.mdx │ │ ├── github-actions-+-aws.mdx │ │ ├── github-actions-and-gcp.mdx │ │ └── gitlab-pipelines-+-aws.mdx │ ├── howto │ │ ├── apply-on-merge.mdx │ │ ├── apply-requirements.mdx │ │ ├── auto-merge.mdx │ │ ├── backendless-mode.mdx │ │ ├── commenting-strategies.mdx │ │ ├── custom-commands.mdx │ │ ├── destroy-manual.mdx │ │ ├── disable-auto-checkout.mdx │ │ ├── disable-locking.mdx │ │ ├── disable-telemetry.mdx │ │ ├── draft-prs.mdx │ │ ├── generate-projects.mdx │ │ ├── group-plans-by-source.mdx │ │ ├── include-exclude-patterns.mdx │ │ ├── multiacc-aws.mdx │ │ ├── policy-overrides.mdx │ │ ├── project-level-roles.mdx │ │ ├── segregate-cloud-accounts.mdx │ │ ├── specify-terraform-version.mdx │ │ ├── store-plans-in-a-bucket.mdx │ │ ├── trigger-directly.mdx │ │ ├── using-checkov.mdx │ │ ├── using-infracost.mdx │ │ ├── using-opa-conftest.mdx │ │ ├── using-terragrunt.mdx │ │ ├── versioning.mdx │ │ └── workspaces.mdx │ ├── reference │ │ ├── action-inputs.mdx │ │ ├── api.mdx │ │ ├── digger.yml.mdx │ │ └── terraform.lock.mdx │ ├── securing-digger │ │ ├── external-provider.mdx │ │ └── spec-signing.mdx │ ├── self-host │ │ ├── auth-methods.mdx │ │ ├── deploy-binary.mdx │ │ ├── deploy-docker-compose.mdx │ │ ├── deploy-docker.mdx │ │ ├── deploy-helm.mdx │ │ └── self-host-on-azure.mdx │ └── troubleshooting │ │ ├── action-errors.mdx │ │ ├── comments.mdx │ │ └── importing-existing-resources.mdx ├── ee │ ├── ai-summaries.mdx │ ├── buildkite.mdx │ ├── dashboard.mdx │ ├── drift-detection.mdx │ ├── ee-setup.mdx │ ├── fips-140.mdx │ ├── gitlab-support.mdx │ ├── gitlab.mdx │ ├── multi-github.mdx │ ├── opa.mdx │ └── rbac.mdx ├── favicon.png ├── images │ ├── Screenshot2025-05-26at19.00.33.png │ ├── Screenshot2025-05-26at19.00.38.png │ ├── Screenshot2025-05-26at19.00.55.png │ ├── Screenshot2025-05-26at19.14.34.png │ ├── Screenshot2025-05-26at19.58.03.png │ ├── Screenshot2025-05-26at21.31.18.png │ ├── buildkite │ │ ├── buildkite.png │ │ └── github_comment.png │ ├── configuration │ │ ├── 1.png │ │ ├── 1.webp │ │ ├── 2.png │ │ ├── 2.webp │ │ ├── 3.webp │ │ ├── 4.png │ │ ├── 5.png │ │ ├── image.png │ │ └── infracost-example.png │ ├── custom-command-output-infracost.png │ ├── digger-dashboard-screenshot.png │ ├── digger-dashboard.png │ ├── digger-plan-preview.png │ ├── drift-issues.png │ ├── ee │ │ ├── ai-summaries.png │ │ ├── example-plan.png │ │ ├── gitlab-1.png │ │ ├── gitlab-2.png │ │ └── multi-tenant-github.png │ ├── gcp │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ └── image.png │ ├── getting-started │ │ ├── 1.webp │ │ ├── 2.webp │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── azure-devops-1.png │ │ ├── azure-devops-2.png │ │ ├── azure-devops-3.png │ │ ├── azure-devops-4.png │ │ ├── azure-devops-5.png │ │ ├── azure-devops-6.png │ │ ├── azure-devops-7.png │ │ ├── azure-devops-8.5.png │ │ ├── azure-devops-8.png │ │ └── image.png │ ├── gitlab │ │ ├── gitlab-apply.png │ │ └── gitlab-plan.png │ ├── infracost-diff-comment-digger.png │ └── readme │ │ └── 1.png ├── logo │ ├── dark.png │ └── light.png ├── mint.json ├── readme │ ├── faq.mdx │ ├── feedback.mdx │ ├── howitworks.mdx │ ├── introduction.mdx │ └── pricing.mdx ├── team │ ├── features │ │ └── variables.mdx │ └── getting-started │ │ └── gha-aws.mdx └── troubleshooting-errors.mdx ├── ee ├── LICENSE ├── backend │ ├── .dockerignore │ ├── .gitignore │ ├── atlas.hcl │ ├── ci_backends │ │ ├── bitbucket_pipeline.go │ │ ├── buildkite.go │ │ ├── gitlab_pipeline.go │ │ └── provider.go │ ├── controllers │ │ ├── artefacts.go │ │ ├── bitbucket.go │ │ ├── bitbucket_utils.go │ │ ├── github.go │ │ ├── gitlab.go │ │ ├── spec.go │ │ └── web.go │ ├── docker-compose.yml │ ├── go.mod │ ├── go.sum │ ├── hooks │ │ └── github.go │ ├── main.go │ ├── providers │ │ └── github │ │ │ └── providers.go │ └── templates │ │ ├── bottom.tmpl │ │ ├── github_connections.tmpl │ │ ├── github_repos.tmpl │ │ ├── github_setup.tmpl │ │ ├── github_success.tmpl │ │ ├── healthy.tmpl │ │ ├── index.tmpl │ │ ├── notifications.tmpl │ │ ├── policies.tmpl │ │ ├── policy_add.tmpl │ │ ├── policy_details.tmpl │ │ ├── project_add.tmpl │ │ ├── project_details.tmpl │ │ ├── projects.tmpl │ │ ├── repo_add.tmpl │ │ ├── repos.tmpl │ │ ├── run_details.tmpl │ │ ├── runs.tmpl │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap.min.css │ │ │ ├── main.css │ │ │ ├── prism.dev.css │ │ │ ├── prism.min.css │ │ │ └── tf.css │ │ ├── js │ │ │ ├── bootstrap.bundle.min.js │ │ │ ├── prism-live-javascript.js │ │ │ ├── prism-live.js │ │ │ ├── prism.dev.js │ │ │ └── prism.min.js │ │ └── prism-live.css │ │ └── top.tmpl ├── cli │ ├── .gitignore │ ├── cmd │ │ └── digger │ │ │ ├── default.go │ │ │ ├── main.go │ │ │ ├── main_test.go │ │ │ ├── root.go │ │ │ └── run_spec.go │ ├── go.mod │ ├── go.sum │ └── pkg │ │ ├── comment_updater │ │ ├── provider.go │ │ └── updater.go │ │ ├── drift │ │ ├── github_issue.go │ │ └── provider.go │ │ ├── github │ │ └── providers.go │ │ ├── gitlab │ │ └── gitlab.go │ │ ├── policy │ │ ├── policy.go │ │ ├── policy_test.go │ │ └── providers.go │ │ ├── utils │ │ └── github.go │ │ └── vcs │ │ └── providers.go └── drift │ ├── .dockerignore │ ├── .gitignore │ ├── README.md │ ├── controllers │ ├── ci_jobs.go │ ├── controllers.go │ ├── drift.go │ ├── github.go │ ├── health.go │ └── notifications.go │ ├── dbgen │ ├── dbgen.go │ ├── go.mod │ └── go.sum │ ├── dbmodels │ ├── ci_jobs.go │ ├── github.go │ ├── projects.go │ ├── repos.go │ ├── setup.go │ ├── storage.go │ └── tokens.go │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── middleware │ ├── job_token.go │ ├── middleware.go │ └── webhooks.go │ ├── model │ ├── digger_ci_job_tokens.gen.go │ ├── digger_ci_jobs.gen.go │ ├── github_app_installation_links.gen.go │ ├── org_settings.gen.go │ ├── organisations.gen.go │ ├── projects.gen.go │ ├── repos.gen.go │ ├── user_settings.gen.go │ └── users.gen.go │ ├── models_generated │ ├── digger_ci_job_tokens.gen.go │ ├── digger_ci_jobs.gen.go │ ├── gen.go │ ├── github_app_installation_links.gen.go │ ├── org_settings.gen.go │ ├── organisations.gen.go │ ├── projects.gen.go │ ├── repos.gen.go │ ├── user_settings.gen.go │ └── users.gen.go │ ├── scripts │ ├── cron │ │ ├── notifications.sql │ │ └── scheduler.sql │ └── entrypoint.sh │ ├── services │ └── spec.go │ ├── tasks │ └── github.go │ └── utils │ └── github.go ├── fly-drift-igor-dev.toml ├── fly-drift.toml ├── fly-pro.toml ├── fly-staging.toml ├── fly.toml ├── go.mod ├── go.work ├── go.work.sum ├── libs ├── backendapi │ ├── backend.go │ ├── diggerapi.go │ └── mocks.go ├── ci │ ├── azure │ │ ├── azure.go │ │ └── azure_test.go │ ├── bitbucket │ │ ├── bitbucket.go │ │ └── bitbucket_service.go │ ├── ci.go │ ├── generic │ │ └── events.go │ ├── github │ │ ├── comment.go │ │ ├── errors.go │ │ ├── github.go │ │ ├── github_test.go │ │ ├── mocks.go │ │ └── models │ │ │ └── models.go │ ├── gitlab │ │ ├── gitlab.go │ │ ├── gitlab_test.go │ │ └── webhooks.go │ ├── mocks.go │ └── utils.go ├── comment_utils │ ├── reporting │ │ ├── core.go │ │ ├── mock.go │ │ ├── noop.go │ │ ├── reporting.go │ │ ├── reporting_test.go │ │ ├── source_grouping.go │ │ └── utils.go │ ├── summary │ │ ├── provider.go │ │ └── updater.go │ └── utils │ │ └── comments.go ├── crypto │ ├── decrypt.go │ └── decrypt_test.go ├── digger_config │ ├── .gitignore │ ├── config.go │ ├── converters.go │ ├── digger_config.go │ ├── digger_config_test.go │ ├── terragrunt │ │ └── atlantis │ │ │ ├── LICENSE │ │ │ ├── config.go │ │ │ ├── generate.go │ │ │ ├── parse_hcl.go │ │ │ ├── parse_locals.go │ │ │ ├── parse_tf.go │ │ │ └── readme.md │ ├── utils.go │ ├── utils_test.go │ ├── validators.go │ └── yaml.go ├── execution │ ├── execution.go │ ├── execution_test.go │ ├── opentofu.go │ ├── opentofu_test.go │ ├── pulumi.go │ ├── runners.go │ ├── terragrunt.go │ ├── test_utils.go │ ├── tf.go │ └── tf_test.go ├── go.mod ├── go.sum ├── iac_utils │ ├── iac_utils.go │ ├── pulumi.go │ ├── terraform.go │ └── terraform_test.go ├── license │ ├── license.go │ └── license_test.go ├── locking │ ├── aws │ │ ├── dynamo_locking.go │ │ ├── dynamo_locking_test.go │ │ └── envprovider │ │ │ ├── envprovider.go │ │ │ └── envprovider_test.go │ ├── azure │ │ ├── storage_account.go │ │ └── storage_account_test.go │ ├── core.go │ ├── gcp │ │ ├── gcp_lock.go │ │ └── gcp_lock_test.go │ ├── locking.go │ ├── locking_test.go │ ├── mock.go │ └── utils.go ├── orchestrator │ ├── .gitignore │ ├── locking.go │ └── mock.go ├── policy │ ├── core.go │ ├── mocks.go │ ├── policy.go │ ├── policy_test.go │ └── providers.go ├── scheduler │ ├── aws.go │ ├── aws_test.go │ ├── convert.go │ ├── jobs.go │ ├── json_models.go │ ├── json_models_test.go │ ├── models.go │ ├── serializers.go │ └── utils.go ├── spec │ ├── models.go │ ├── models_test.go │ ├── payloads.go │ ├── providers.go │ ├── variables_provider.go │ └── variables_provider_test.go └── storage │ ├── aws_plan_storage.go │ ├── aws_plan_storage_test.go │ ├── azure_plan_storage.go │ ├── gcp_plan_storage.go │ ├── io.go │ ├── io_test.go │ ├── mocks.go │ ├── plan_storage.go │ └── storage.go └── next ├── .gitignore ├── ci_backends ├── ci_backends.go ├── github_actions.go ├── jenkins.go └── provider.go ├── controllers ├── drift.go ├── github.go ├── github_after_merge.go ├── projects.go ├── runs.go └── static.go ├── dbgen ├── dbgen.go ├── go.mod └── go.sum ├── dbmodels ├── github.go ├── orgs.go ├── projects.go ├── runs.go ├── scheduler.go ├── setup.go ├── storage.go └── variables.go ├── go.mod ├── go.sum ├── main.go ├── middleware ├── job_token_auth.go ├── middleware.go ├── supabase_cookie_auth.go └── webhooks.go ├── model ├── account_delete_tokens.gen.go ├── billing_bypass_organizations.gen.go ├── chats.gen.go ├── customers.gen.go ├── digger_batches.gen.go ├── digger_job_parent_links.gen.go ├── digger_job_summaries.gen.go ├── digger_job_tokens.gen.go ├── digger_jobs.gen.go ├── digger_locks.gen.go ├── digger_run_queue_items.gen.go ├── digger_run_stages.gen.go ├── digger_runs.gen.go ├── env_vars.gen.go ├── github_app_installation_links.gen.go ├── github_app_installations.gen.go ├── github_apps.gen.go ├── internal_blog_author_posts.gen.go ├── internal_blog_author_profiles.gen.go ├── internal_blog_post_tags.gen.go ├── internal_blog_post_tags_relationship.gen.go ├── internal_blog_posts.gen.go ├── internal_changelog.gen.go ├── internal_feedback_comments.gen.go ├── internal_feedback_threads.gen.go ├── organization_credits.gen.go ├── organization_join_invitations.gen.go ├── organization_members.gen.go ├── organizations.gen.go ├── organizations_private_info.gen.go ├── prices.gen.go ├── products.gen.go ├── project_comments.gen.go ├── project_tfvars.gen.go ├── projects.gen.go ├── repos.gen.go ├── subscriptions.gen.go ├── team_members.gen.go ├── teams.gen.go ├── user_api_keys.gen.go ├── user_m2m_applications.gen.go ├── user_notifications.gen.go ├── user_onboarding.gen.go ├── user_private_info.gen.go ├── user_profiles.gen.go └── user_roles.gen.go ├── models_generated ├── account_delete_tokens.gen.go ├── billing_bypass_organizations.gen.go ├── chats.gen.go ├── customers.gen.go ├── digger_batches.gen.go ├── digger_job_parent_links.gen.go ├── digger_job_summaries.gen.go ├── digger_job_tokens.gen.go ├── digger_jobs.gen.go ├── digger_locks.gen.go ├── digger_run_queue_items.gen.go ├── digger_run_stages.gen.go ├── digger_runs.gen.go ├── env_vars.gen.go ├── gen.go ├── github_app_installation_links.gen.go ├── github_app_installations.gen.go ├── github_apps.gen.go ├── internal_blog_author_posts.gen.go ├── internal_blog_author_profiles.gen.go ├── internal_blog_post_tags.gen.go ├── internal_blog_post_tags_relationship.gen.go ├── internal_blog_posts.gen.go ├── internal_changelog.gen.go ├── internal_feedback_comments.gen.go ├── internal_feedback_threads.gen.go ├── organization_credits.gen.go ├── organization_join_invitations.gen.go ├── organization_members.gen.go ├── organizations.gen.go ├── organizations_private_info.gen.go ├── prices.gen.go ├── products.gen.go ├── project_comments.gen.go ├── project_tfvars.gen.go ├── projects.gen.go ├── repos.gen.go ├── subscriptions.gen.go ├── team_members.gen.go ├── teams.gen.go ├── user_api_keys.gen.go ├── user_m2m_applications.gen.go ├── user_notifications.gen.go ├── user_onboarding.gen.go ├── user_private_info.gen.go ├── user_profiles.gen.go └── user_roles.gen.go ├── scripts ├── cron │ ├── process_drift.query │ └── process_runs_queue.query └── entrypoint.sh ├── services ├── config.go ├── drift.go ├── runs.go ├── scheduler.go └── spec.go ├── supa └── supa.go ├── templates ├── github_repos.tmpl ├── github_setup.tmpl ├── github_success.tmpl ├── home.tmpl ├── index.tmpl ├── static │ ├── css │ │ ├── bootstrap.min.css │ │ ├── main.css │ │ ├── prism.dev.css │ │ ├── prism.min.css │ │ └── tf.css │ ├── js │ │ ├── bootstrap.bundle.min.js │ │ ├── prism-live-javascript.js │ │ ├── prism-live.js │ │ ├── prism.dev.js │ │ └── prism.min.js │ └── prism-live.css └── top.tmpl └── utils ├── crontab.go ├── crontab_test.go └── github.go /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ], 6 | "labels": ["dependencies"], 7 | "vulnerabilityAlerts": { 8 | "labels": ["security"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/backend_release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Backend release 3 | 4 | "on": 5 | release: 6 | types: 7 | - 'released' 8 | 9 | jobs: 10 | binary: 11 | strategy: 12 | matrix: 13 | arch: [arm, arm64, amd64, "386"] 14 | os: [linux, darwin, freebsd, windows] 15 | exclude: 16 | - os: darwin 17 | arch: arm 18 | - os: darwin 19 | arch: "386" 20 | 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - name: Check out repository 25 | uses: actions/checkout@v4 26 | 27 | - name: Build and publish binary artifact to GitHub 28 | id: build-and-release-binary 29 | uses: wangyoucao577/go-release-action@8fa1e8368c8465264d64e0198208e10f71474c87 # v1.50 30 | with: 31 | github_token: ${{ secrets.GITHUB_TOKEN }} 32 | goos: ${{ matrix.os }} 33 | goarch: ${{ matrix.arch }} 34 | goversion: 1.24.0 35 | project_path: ./backend 36 | binary_name: digger-api 37 | pre_command: export CGO_ENABLED=0 38 | ldflags: ${{ matrix.ldflags }} 39 | sha256sum: true 40 | md5sum: false 41 | asset_name: "digger-api-${{matrix.os}}-${{matrix.arch}}" 42 | compress_assets: "OFF" 43 | -------------------------------------------------------------------------------- /.github/workflows/backend_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Backend Go Tests 3 | 4 | "on": 5 | push: 6 | branches: ['develop'] 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Download Go 16 | uses: actions/setup-go@v5 17 | with: 18 | go-version: 1.24.0 19 | id: go 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v4 23 | 24 | - name: Test that the docker image still builds successfully 25 | run: | 26 | export COMMIT_SHA=$(git rev-parse --short HEAD) 27 | docker build -t testingbuild:latest --build-arg COMMIT_SHA=${COMMIT_SHA} . -f Dockerfile_backend 28 | 29 | - name: Deps 30 | run: go get -v ./... 31 | working-directory: backend 32 | 33 | - name: Build 34 | run: go build 35 | working-directory: backend 36 | 37 | - name: Test 38 | run: | 39 | go test ./... 40 | env: 41 | GITHUB_PAT_TOKEN: ${{ secrets.TOKEN_GITHUB }} 42 | working-directory: backend 43 | -------------------------------------------------------------------------------- /.github/workflows/cli_release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release cli 3 | 4 | "on": 5 | release: 6 | branches: 7 | - 'go' 8 | types: 9 | - 'released' 10 | 11 | jobs: 12 | binary: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Check out repository 17 | uses: actions/checkout@v4 18 | 19 | - name: Publish linux-x64 exec to github 20 | id: build-and-release-binary 21 | uses: wangyoucao577/go-release-action@8fa1e8368c8465264d64e0198208e10f71474c87 # v1.50 22 | with: 23 | github_token: ${{ secrets.GITHUB_TOKEN }} 24 | goos: linux 25 | goarch: amd64 26 | goversion: 1.24.0 27 | project_path: ./cli/cmd/digger 28 | binary_name: digger 29 | pre_command: export CGO_ENABLED=0 30 | ldflags: ${{ matrix.ldflags }} 31 | sha256sum: true 32 | md5sum: false 33 | asset_name: "digger-cli-Linux-X64" 34 | compress_assets: "OFF" 35 | -------------------------------------------------------------------------------- /.github/workflows/cli_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Cli tests 3 | 4 | "on": 5 | push: 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Download Go 15 | uses: actions/setup-go@v5 16 | with: 17 | go-version: 1.24.0 18 | id: go 19 | 20 | - name: Setup Opentofu 21 | uses: opentofu/setup-opentofu@v1 22 | with: 23 | tofu_version: 1.8.5 24 | 25 | - name: Check out code into the Go module directory 26 | uses: actions/checkout@v4 27 | 28 | - name: Deps 29 | run: | 30 | go get -v ./... 31 | working-directory: cli 32 | 33 | - name: Build 34 | run: | 35 | go build -v ./cmd/digger 36 | working-directory: cli 37 | 38 | - name: Test 39 | shell: bash 40 | run: | 41 | go test ./... 42 | working-directory: cli 43 | -------------------------------------------------------------------------------- /.github/workflows/drift_deploy.yml: -------------------------------------------------------------------------------- 1 | name: driftapp Deploy 2 | on: 3 | push: 4 | branches: 5 | - develop # change to main if needed 6 | - feat-drift-app 7 | jobs: 8 | deploy: 9 | name: Deploy app 10 | runs-on: ubuntu-latest 11 | concurrency: deploy-group # optional: ensure only one action runs at a time 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: superfly/flyctl-actions/setup-flyctl@master 15 | - run: flyctl deploy --remote-only --config fly-drift.toml 16 | env: 17 | FLY_API_TOKEN: ${{ secrets.FLYIO_DRIFT_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/ee_backend_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: EE Backend Go Tests 3 | 4 | "on": 5 | push: 6 | branches: ['develop'] 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Download Go 16 | uses: actions/setup-go@v5 17 | with: 18 | go-version: 1.24.0 19 | id: go 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v4 23 | 24 | - name: Test that the docker image still builds successfully 25 | run: | 26 | export COMMIT_SHA=$(git rev-parse --short HEAD) 27 | docker build -t testingbuild:latest --build-arg COMMIT_SHA=${COMMIT_SHA} . -f Dockerfile_backend 28 | 29 | - name: Deps 30 | run: go get -v ./... 31 | working-directory: ee/backend 32 | 33 | - name: Build 34 | run: go build 35 | working-directory: ee/backend 36 | 37 | - name: Test 38 | run: go test -v ./... 39 | env: 40 | GITHUB_PAT_TOKEN: ${{ secrets.TOKEN_GITHUB }} 41 | working-directory: ee/backend 42 | -------------------------------------------------------------------------------- /.github/workflows/ee_cli_release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release ee cli 3 | 4 | "on": 5 | release: 6 | branches: 7 | - 'go' 8 | types: 9 | - 'released' 10 | 11 | jobs: 12 | binary: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Download Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: 1.24.0 20 | id: go 21 | 22 | - name: Check out repository 23 | uses: actions/checkout@v4 24 | 25 | - name: Publish linux-x64 exec to github 26 | id: build-and-release-binary 27 | uses: wangyoucao577/go-release-action@8fa1e8368c8465264d64e0198208e10f71474c87 # v1.50 28 | with: 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | goos: linux 31 | goarch: amd64 32 | goversion: 1.24.0 33 | project_path: ./ee/cli/cmd/digger 34 | binary_name: digger 35 | pre_command: export CGO_ENABLED=0 36 | ldflags: ${{ matrix.ldflags }} 37 | sha256sum: true 38 | md5sum: false 39 | asset_name: "digger-ee-cli-Linux-X64" 40 | compress_assets: "OFF" 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/ee_cli_release_fips.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release ee cli 3 | 4 | "on": 5 | release: 6 | branches: 7 | - 'go' 8 | types: 9 | - 'released' 10 | 11 | jobs: 12 | binary: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Download Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: 1.24.0 20 | id: go 21 | 22 | - name: Check out repository 23 | uses: actions/checkout@v4 24 | 25 | - name: Publish linux-x64 exec to github 26 | id: build-and-release-binary 27 | uses: wangyoucao577/go-release-action@8fa1e8368c8465264d64e0198208e10f71474c87 # v1.50 28 | with: 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | goos: linux 31 | goarch: amd64 32 | goversion: 1.24.0 33 | project_path: ./ee/cli/cmd/digger 34 | binary_name: digger 35 | pre_command: export CGO_ENABLED=0 36 | sha256sum: true 37 | md5sum: false 38 | asset_name: "digger-ee-cli-Linux-X64-fips" 39 | compress_assets: "OFF" 40 | env: 41 | GODEBUG: fips140=only 42 | GOFIPS140: v1.0.0 43 | 44 | -------------------------------------------------------------------------------- /.github/workflows/ee_cli_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: EE Cli tests 3 | 4 | "on": 5 | push: 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Download Go 15 | uses: actions/setup-go@v5 16 | with: 17 | go-version: 1.24.0 18 | id: go 19 | 20 | - name: Setup Opentofu 21 | uses: opentofu/setup-opentofu@v1 22 | with: 23 | tofu_version: 1.8.5 24 | 25 | - name: Check out code into the Go module directory 26 | uses: actions/checkout@v4 27 | 28 | - name: Deps 29 | run: | 30 | go get -v ./... 31 | working-directory: ee/cli 32 | 33 | - name: Build 34 | run: | 35 | go build -v ./cmd/digger 36 | working-directory: ee/cli 37 | 38 | - name: Test 39 | run: go test -v ./... 40 | working-directory: ee/cli 41 | -------------------------------------------------------------------------------- /.github/workflows/misc_top_issues.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Top issues updater 3 | 4 | "on": 5 | schedule: 6 | - cron: "0 * * * *" # every hour 7 | workflow_dispatch: 8 | 9 | jobs: 10 | get-top-issues: 11 | if: github.repository_owner == 'diggerhq' 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: update-top-issues 16 | uses: diggerhq/top-issues@main 17 | with: 18 | org_name: diggerhq 19 | repo_name: digger 20 | issue_number: 1352 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/next_deploy.yml: -------------------------------------------------------------------------------- 1 | name: Next Deploy 2 | on: 3 | push: 4 | branches: 5 | - develop # change to main if needed 6 | - feat/regen-db 7 | jobs: 8 | deploy: 9 | name: Deploy app 10 | runs-on: ubuntu-latest 11 | concurrency: next-deploy-group # optional: ensure only one action runs at a time 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: superfly/flyctl-actions/setup-flyctl@master 15 | - run: flyctl deploy --remote-only 16 | env: 17 | FLY_API_TOKEN: ${{ secrets.FLYIO_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/next_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Next Go Tests 3 | 4 | "on": 5 | push: 6 | branches: ['develop'] 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Download Go 16 | uses: actions/setup-go@v5 17 | with: 18 | go-version: 1.24.0 19 | id: go 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v4 23 | 24 | - name: Test that the docker image still builds successfully 25 | run: | 26 | export COMMIT_SHA=$(git rev-parse --short HEAD) 27 | docker build -t testingbuild:latest --build-arg COMMIT_SHA=${COMMIT_SHA} . -f Dockerfile_next 28 | 29 | - name: Deps 30 | run: go get -v ./... 31 | working-directory: backend 32 | 33 | - name: Build 34 | run: go build 35 | working-directory: backend 36 | 37 | - name: Test 38 | run: go test -v ./... 39 | env: 40 | GITHUB_PAT_TOKEN: ${{ secrets.TOKEN_GITHUB }} 41 | working-directory: next 42 | -------------------------------------------------------------------------------- /.github/workflows/pro-deploy.yml: -------------------------------------------------------------------------------- 1 | # See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ 2 | 3 | name: Deploy pro-backend 4 | on: 5 | push: 6 | branches: 7 | - develop 8 | - pro 9 | jobs: 10 | deploy: 11 | name: Deploy app 12 | runs-on: ubuntu-latest 13 | concurrency: deploy-group # optional: ensure only one action runs at a time 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: superfly/flyctl-actions/setup-flyctl@master 17 | - run: flyctl deploy --remote-only --config fly-pro.toml 18 | env: 19 | FLY_API_TOKEN: ${{ secrets.FLYIO_PRO_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/tasks_run_test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Tasks run tests 3 | 4 | "on": 5 | push: 6 | pull_request: 7 | 8 | jobs: 9 | build: 10 | name: Build 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Download Go 15 | uses: actions/setup-go@v5 16 | with: 17 | go-version: 1.24.0 18 | id: go 19 | 20 | - name: Check out code into the Go module directory 21 | uses: actions/checkout@v4 22 | 23 | - name: Deps 24 | run: | 25 | pwd 26 | go get -v ./... 27 | working-directory: backend/tasks 28 | 29 | - name: Test 30 | run: go test -v ./... 31 | working-directory: backend/tasks 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | **/.env 3 | **/.env* 4 | .DS_Store 5 | venv/ 6 | **/__pycache__/ 7 | __azurite* 8 | -------------------------------------------------------------------------------- /Dockerfile_tasks: -------------------------------------------------------------------------------- 1 | FROM golang:1.22 as builder 2 | ARG COMMIT_SHA 3 | RUN echo "commit sha: ${COMMIT_SHA}" 4 | 5 | # Set the working directory 6 | WORKDIR $GOPATH/src/github.com/diggerhq/digger 7 | 8 | # Copy all required source, blacklist files that are not required through `.dockerignore` 9 | COPY . . 10 | 11 | # Get the vendor library 12 | RUN go version 13 | 14 | # RUN vgo install 15 | 16 | # https://github.com/ethereum/go-ethereum/issues/2738 17 | # Build static binary "-getmode=vendor" does not work with go-ethereum 18 | 19 | RUN go build -ldflags="-X 'main.Version=${COMMIT_SHA}'" -o tasks_exe ./backend/tasks 20 | 21 | # Multi-stage build will just copy the binary to an alpine image. 22 | FROM ubuntu:24.04 as runner 23 | ENV ATLAS_VERSION v0.28.0 24 | ARG COMMIT_SHA 25 | WORKDIR /app 26 | 27 | RUN apt-get update && apt-get install -y ca-certificates curl && apt-get install -y git && apt-get clean all 28 | RUN update-ca-certificates 29 | 30 | RUN echo "commit sha: ${COMMIT_SHA}" 31 | 32 | # install atlas 33 | RUN curl -sSf https://atlasgo.sh | sh 34 | 35 | 36 | # Copy the binary to the corresponding folder 37 | COPY --from=builder /go/src/github.com/diggerhq/digger/tasks_exe /app/tasks 38 | 39 | # Run the binary 40 | ENTRYPOINT ["/app/tasks"] 41 | -------------------------------------------------------------------------------- /backend/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | cloud -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | backend 2 | main 3 | .idea/ 4 | .DS_Store 5 | venv/ 6 | **/__pycache__/ 7 | __azurite* 8 | ./digger 9 | cloud 10 | *.env 11 | *.env.* 12 | .docker-compose-env 13 | controllers/database_test.db 14 | -------------------------------------------------------------------------------- /backend/Makefile: -------------------------------------------------------------------------------- 1 | # Include only if exist 2 | -include .env 3 | export 4 | 5 | start: 6 | go run main.go -------------------------------------------------------------------------------- /backend/atlas.hcl: -------------------------------------------------------------------------------- 1 | data "external_schema" "gorm" { 2 | program = [ 3 | "go", 4 | "run", 5 | "-mod=mod", 6 | "ariga.io/atlas-provider-gorm", 7 | "load", 8 | "--path", "./models", 9 | "--dialect", "postgres", 10 | ] 11 | } 12 | 13 | env "gorm" { 14 | src = data.external_schema.gorm.url 15 | dev = "docker://postgres/16.1" 16 | migration { 17 | dir = "file://migrations" 18 | } 19 | format { 20 | migrate { 21 | diff = "{{ sql . \" \" }}" 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /backend/ci_backends/ci_backends.go: -------------------------------------------------------------------------------- 1 | package ci_backends 2 | 3 | import ( 4 | "github.com/diggerhq/digger/backend/utils" 5 | "github.com/diggerhq/digger/libs/spec" 6 | ) 7 | 8 | type CiBackend interface { 9 | TriggerWorkflow(spec spec.Spec, runName string, vcsToken string) error 10 | GetWorkflowUrl(spec spec.Spec) (string, error) 11 | } 12 | 13 | type JenkinsCi struct{} 14 | 15 | type CiBackendOptions struct { 16 | GithubClientProvider utils.GithubClientProvider 17 | GithubInstallationId int64 18 | GithubAppId int64 19 | GitlabProjectId int 20 | GitlabmergeRequestEventName string 21 | GitlabCIPipelineID string 22 | GitlabCIPipelineIID int 23 | GitlabCIMergeRequestID int 24 | GitlabCIMergeRequestIID int 25 | GitlabCIProjectName string 26 | GitlabciprojectNamespace string 27 | GitlabciprojectId int 28 | GitlabciprojectNamespaceId int 29 | GitlabDiscussionId string 30 | RepoFullName string 31 | RepoOwner string 32 | RepoName string 33 | } 34 | -------------------------------------------------------------------------------- /backend/ci_backends/jenkins.go: -------------------------------------------------------------------------------- 1 | package ci_backends 2 | -------------------------------------------------------------------------------- /backend/ci_backends/provider.go: -------------------------------------------------------------------------------- 1 | package ci_backends 2 | 3 | import ( 4 | "fmt" 5 | "log/slog" 6 | 7 | "github.com/diggerhq/digger/backend/utils" 8 | ) 9 | 10 | type CiBackendProvider interface { 11 | GetCiBackend(options CiBackendOptions) (CiBackend, error) 12 | } 13 | 14 | type DefaultBackendProvider struct{} 15 | 16 | func (d DefaultBackendProvider) GetCiBackend(options CiBackendOptions) (CiBackend, error) { 17 | client, _, err := utils.GetGithubClientFromAppId(options.GithubClientProvider, options.GithubInstallationId, options.GithubAppId, options.RepoFullName) 18 | if err != nil { 19 | slog.Error("GetCiBackend: could not get github client", "error", err) 20 | return nil, fmt.Errorf("could not get github client: %v", err) 21 | } 22 | backend := &GithubActionCi{ 23 | Client: client, 24 | } 25 | return backend, nil 26 | } 27 | -------------------------------------------------------------------------------- /backend/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/spf13/cast" 5 | "os" 6 | "strings" 7 | "time" 8 | 9 | "github.com/spf13/viper" 10 | ) 11 | 12 | // Config represents an alias to viper config 13 | type Config = viper.Viper 14 | 15 | var DiggerConfig *Config 16 | 17 | // New returns a new pointer to the config 18 | func New() *Config { 19 | v := viper.New() 20 | v.SetEnvPrefix("DIGGER") 21 | v.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) 22 | v.SetDefault("port", 3000) 23 | v.SetDefault("usersvc_on", true) 24 | v.SetDefault("build_date", "null") 25 | v.SetDefault("deployed_at", time.Now().UTC().Format(time.RFC3339)) 26 | v.SetDefault("max_concurrency_per_batch", "0") 27 | v.BindEnv() 28 | return v 29 | } 30 | 31 | func GetPort() int { 32 | port := cast.ToInt(os.Getenv("PORT")) 33 | if port == 0 { 34 | port = 3000 35 | } 36 | return port 37 | } 38 | 39 | func init() { 40 | cfg := New() 41 | cfg.AutomaticEnv() 42 | DiggerConfig = cfg 43 | } 44 | -------------------------------------------------------------------------------- /backend/config/envgetters.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func LimitByNumOfFilesChanged() bool { 8 | // if this flag is set then it will fail if there are more projects impacted than the 9 | // number of files changed 10 | return os.Getenv("DIGGER_LIMIT_MAX_PROJECTS_TO_FILES_CHANGED") == "1" 11 | } 12 | -------------------------------------------------------------------------------- /backend/controllers/helpers.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func Home(c *gin.Context) { 9 | c.HTML(http.StatusOK, "home.tmpl", gin.H{}) 10 | } 11 | -------------------------------------------------------------------------------- /backend/controllers/locking.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | -------------------------------------------------------------------------------- /backend/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | postgres: 5 | image: postgres:alpine 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | - POSTGRES_PASSWORD=23q4RSDFSDFS 10 | healthcheck: 11 | test: [ "CMD-SHELL", "pg_isready -U postgres" ] 12 | interval: 5s 13 | timeout: 5s 14 | retries: 5 15 | 16 | web: 17 | links: 18 | - postgres 19 | depends_on: 20 | postgres: 21 | condition: service_healthy 22 | build: ./ 23 | env_file: 24 | - .env.docker-compose 25 | environment: 26 | - ALLOW_DIRTY=false 27 | ports: 28 | - "3100:3000" 29 | -------------------------------------------------------------------------------- /backend/hooks/hooks.go: -------------------------------------------------------------------------------- 1 | package hooks 2 | -------------------------------------------------------------------------------- /backend/locking/backend_locking.go: -------------------------------------------------------------------------------- 1 | package locking 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/diggerhq/digger/backend/models" 7 | "gorm.io/gorm" 8 | ) 9 | 10 | type BackendDBLock struct { 11 | OrgId uint 12 | } 13 | 14 | func (lock BackendDBLock) Lock(lockId int, resource string) (bool, error) { 15 | _, err := models.DB.CreateDiggerLock(resource, lockId, lock.OrgId) 16 | if err != nil { 17 | return false, fmt.Errorf("could not create lock record: %v", err) 18 | } 19 | return true, nil 20 | } 21 | 22 | func (lock BackendDBLock) Unlock(resource string) (bool, error) { 23 | // delete all locks that match this resource 24 | l := models.DiggerLock{} 25 | err := models.DB.GormDB.Where("resource=?", resource).Delete(&l).Error 26 | if err != nil { 27 | return false, fmt.Errorf("could not delete all locks: %v", err) 28 | } 29 | return true, nil 30 | } 31 | 32 | func (lock BackendDBLock) GetLock(resource string) (*int, error) { 33 | theLock, err := models.DB.GetDiggerLock(resource) 34 | if errors.Is(err, gorm.ErrRecordNotFound) { 35 | return nil, nil 36 | } 37 | if err != nil { 38 | return nil, fmt.Errorf("could not get lock record: %v", err) 39 | } 40 | return &theLock.LockId, nil 41 | } 42 | -------------------------------------------------------------------------------- /backend/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "fmt" 6 | "github.com/diggerhq/digger/backend/bootstrap" 7 | "github.com/diggerhq/digger/backend/ci_backends" 8 | "github.com/diggerhq/digger/backend/config" 9 | "github.com/diggerhq/digger/backend/controllers" 10 | "github.com/diggerhq/digger/backend/utils" 11 | ) 12 | 13 | //go:embed templates 14 | var templates embed.FS 15 | 16 | func main() { 17 | ghController := controllers.DiggerController{ 18 | CiBackendProvider: ci_backends.DefaultBackendProvider{}, 19 | GithubClientProvider: utils.DiggerGithubRealClientProvider{}, 20 | GithubWebhookPostIssueCommentHooks: make([]controllers.IssueCommentHook, 0), 21 | } 22 | r := bootstrap.Bootstrap(templates, ghController) 23 | r.GET("/", controllers.Home) 24 | port := config.GetPort() 25 | r.Run(fmt.Sprintf(":%d", port)) 26 | } 27 | -------------------------------------------------------------------------------- /backend/middleware/headers.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func HeadersApiAuth() gin.HandlerFunc { 9 | return func(c *gin.Context) { 10 | orgId := c.Request.Header.Get("DIGGER_ORG_ID") 11 | orgSource := c.Request.Header.Get("DIGGER_ORG_SOURCE") 12 | userId := c.Request.Header.Get("DIGGER_USER_ID") 13 | 14 | if orgId == "" { 15 | c.String(http.StatusBadRequest, "Missing parameter: DIGGER_ORG_ID") 16 | c.Abort() 17 | return 18 | } 19 | 20 | if orgSource == "" { 21 | c.String(http.StatusBadRequest, "Missing parameter: DIGGER_ORG_SOURCE") 22 | c.Abort() 23 | return 24 | } 25 | 26 | if userId == "" { 27 | c.String(http.StatusBadRequest, "Missing parameter: DIGGER_USER_ID") 28 | c.Abort() 29 | return 30 | } 31 | 32 | c.Set(ORGANISATION_ID_KEY, orgId) 33 | c.Set(ORGANISATION_SOURCE_KEY, orgSource) 34 | c.Set(USER_ID_KEY, userId) 35 | 36 | c.Next() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/middleware/noop.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/diggerhq/digger/backend/models" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func NoopWebAuth() gin.HandlerFunc { 9 | return func(c *gin.Context) { 10 | setDefaultOrganisationId(c) 11 | c.Set(ACCESS_LEVEL_KEY, models.AdminPolicyType) 12 | c.Next() 13 | } 14 | } 15 | 16 | func NoopApiAuth() gin.HandlerFunc { 17 | return func(c *gin.Context) { 18 | setDefaultOrganisationId(c) 19 | c.Set(ACCESS_LEVEL_KEY, models.AdminPolicyType) 20 | c.Next() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /backend/middleware/webhook.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func InternalApiAuth() gin.HandlerFunc { 11 | return func(c *gin.Context) { 12 | webhookSecret := os.Getenv("DIGGER_INTERNAL_SECRET") 13 | authHeader := c.Request.Header.Get("Authorization") 14 | if authHeader == "" { 15 | c.String(http.StatusForbidden, "No Authorization header provided") 16 | c.Abort() 17 | return 18 | } 19 | token := strings.TrimPrefix(authHeader, "Bearer ") 20 | if token != webhookSecret { 21 | c.String(http.StatusForbidden, "invalid token") 22 | c.Abort() 23 | return 24 | } 25 | // webhook auth optionally accepts organisation ID as a value 26 | orgIdHeader := c.GetHeader("X-Digger-Org-ID") 27 | if orgIdHeader != "" { 28 | c.Set(ORGANISATION_ID_KEY, orgIdHeader) 29 | } 30 | 31 | c.Next() 32 | return 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /backend/migrations/20240115170600.sql: -------------------------------------------------------------------------------- 1 | -- Create "digger_job_summaries" table 2 | CREATE TABLE "public"."digger_job_summaries" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "resources_created" bigint NULL, 8 | "resources_deleted" bigint NULL, 9 | "resources_updated" bigint NULL, 10 | PRIMARY KEY ("id") 11 | ); 12 | -- Create index "idx_digger_job_summaries_deleted_at" to table: "digger_job_summaries" 13 | CREATE INDEX "idx_digger_job_summaries_deleted_at" ON "public"."digger_job_summaries" ("deleted_at"); 14 | -- Modify "digger_jobs" table 15 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "digger_job_summary_id" bigint NULL, ADD 16 | CONSTRAINT "fk_digger_jobs_digger_job_summary" FOREIGN KEY ("digger_job_summary_id") REFERENCES "public"."digger_job_summaries" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 17 | -------------------------------------------------------------------------------- /backend/migrations/20240116123649.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "comment_id" bigint NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240125121106.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" DROP COLUMN "serialized_job", ADD COLUMN "serialized_job_spec" bytea NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240125181812.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "workflow_run_url" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240301211741.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "workflow_file" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240328182453.sql: -------------------------------------------------------------------------------- 1 | -- Modify "repos" table 2 | ALTER TABLE "public"."repos" ADD COLUMN "repo_full_name" text NULL, ADD COLUMN "repo_organisation" text NULL, ADD COLUMN "repo_name" text NULL, ADD COLUMN "repo_url" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240329114422.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_run_stages" table 2 | ALTER TABLE "public"."digger_run_stages" DROP COLUMN "digger_run_stage_id", DROP COLUMN "project_name", DROP COLUMN "status", DROP COLUMN "digger_job_summary_id", DROP COLUMN "serialized_job_spec", DROP COLUMN "workflow_file", DROP COLUMN "workflow_run_url", ADD COLUMN "batch_id" text NULL, ADD 3 | CONSTRAINT "fk_digger_run_stages_batch" FOREIGN KEY ("batch_id") REFERENCES "public"."digger_batches" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 4 | -------------------------------------------------------------------------------- /backend/migrations/20240403155357_drop_dup_idx.sql: -------------------------------------------------------------------------------- 1 | -- drop the duplicate index to fix the next migration of renaming 2 | DROP INDEX "public"."idx_digger_job_id"; 3 | DROP INDEX "idx_digger_run_queues_deleted_at"; 4 | DROP INDEX "idx_digger_run_queue_project_id"; 5 | DROP INDEX "idx_digger_run_queue_run_id"; 6 | -------------------------------------------------------------------------------- /backend/migrations/20240404160724.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_run_queue_items" table 2 | ALTER TABLE "public"."digger_run_queue_items" DROP COLUMN "project_id"; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240404161121.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_run_stages" table 2 | ALTER TABLE "public"."digger_run_stages" DROP COLUMN "run_id"; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240404161723.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_runs" table 2 | ALTER TABLE "public"."digger_runs" ADD COLUMN "plan_stage_id" bigint NULL, ADD COLUMN "apply_stage_id" bigint NULL, ADD 3 | CONSTRAINT "fk_digger_runs_apply_stage" FOREIGN KEY ("apply_stage_id") REFERENCES "public"."digger_run_stages" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD 4 | CONSTRAINT "fk_digger_runs_plan_stage" FOREIGN KEY ("plan_stage_id") REFERENCES "public"."digger_run_stages" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 5 | -------------------------------------------------------------------------------- /backend/migrations/20240404165910.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_runs" table 2 | ALTER TABLE "public"."digger_runs" DROP COLUMN "project_id", ADD COLUMN "project_name" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240405150942.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_runs" table 2 | ALTER TABLE "public"."digger_runs" ADD COLUMN "is_approved" boolean NULL, ADD COLUMN "approval_author" text NULL, ADD COLUMN "approval_date" timestamptz NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240405160110.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_run_queue_items" table 2 | ALTER TABLE "public"."digger_run_queue_items" ADD COLUMN "project_id" bigint NULL, ADD 3 | CONSTRAINT "fk_digger_run_queue_items_project" FOREIGN KEY ("project_id") REFERENCES "public"."projects" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 4 | -------------------------------------------------------------------------------- /backend/migrations/20240409161739.sql: -------------------------------------------------------------------------------- 1 | -- Create "job_tokens" table 2 | CREATE TABLE "public"."job_tokens" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "value" text NULL, 8 | "expiry" timestamptz NULL, 9 | "organisation_id" bigint NULL, 10 | "type" text NULL, 11 | PRIMARY KEY ("id"), 12 | CONSTRAINT "fk_job_tokens_organisation" FOREIGN KEY ("organisation_id") REFERENCES "public"."organisations" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION 13 | ); 14 | -- Create index "idx_job_tokens_deleted_at" to table: "job_tokens" 15 | CREATE INDEX "idx_job_tokens_deleted_at" ON "public"."job_tokens" ("deleted_at"); 16 | -------------------------------------------------------------------------------- /backend/migrations/20240510162721.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "plan_footprint" bytea NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240518182629.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "pr_comment_url" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240524110010.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "terraform_output" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240527112209.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "source_details" bytea NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240530074832.sql: -------------------------------------------------------------------------------- 1 | -- Create "digger_locks" table 2 | CREATE TABLE "public"."digger_locks" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "resource" text NULL, 8 | "lock_id" bigint NULL, 9 | "organisation_id" bigint NULL, 10 | PRIMARY KEY ("id"), 11 | CONSTRAINT "fk_digger_locks_organisation" FOREIGN KEY ("organisation_id") REFERENCES "public"."organisations" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION 12 | ); 13 | -- Create index "idx_digger_locked_resource" to table: "digger_locks" 14 | CREATE INDEX "idx_digger_locked_resource" ON "public"."digger_locks" ("resource"); 15 | -- Create index "idx_digger_locks_deleted_at" to table: "digger_locks" 16 | CREATE INDEX "idx_digger_locks_deleted_at" ON "public"."digger_locks" ("deleted_at"); 17 | -------------------------------------------------------------------------------- /backend/migrations/20240703121051.sql: -------------------------------------------------------------------------------- 1 | -- Modify "projects" table 2 | ALTER TABLE "public"."projects" ADD COLUMN "is_generated" boolean NULL, ADD COLUMN "is_in_main_branch" boolean NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240704192835.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "vcs" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240705144450.sql: -------------------------------------------------------------------------------- 1 | -- Modify "project_runs" table 2 | ALTER TABLE "public"."project_runs" ADD COLUMN "actor_username" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240709165155.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "gitlab_project_id" bigint NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240729155442.sql: -------------------------------------------------------------------------------- 1 | -- Create "job_artefacts" table 2 | CREATE TABLE "public"."job_artefacts" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "job_token_id" bigint NULL, 8 | "contents" bytea NULL, 9 | PRIMARY KEY ("id"), 10 | CONSTRAINT "fk_job_artefacts_job_token" FOREIGN KEY ("job_token_id") REFERENCES "public"."job_tokens" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION 11 | ); 12 | -- Create index "idx_job_artefacts_deleted_at" to table: "job_artefacts" 13 | CREATE INDEX "idx_job_artefacts_deleted_at" ON "public"."job_artefacts" ("deleted_at"); 14 | -------------------------------------------------------------------------------- /backend/migrations/20240729155926.sql: -------------------------------------------------------------------------------- 1 | -- Modify "job_artefacts" table 2 | ALTER TABLE "public"."job_artefacts" ADD COLUMN "size" bigint NULL, ADD COLUMN "content_type" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20240729160028.sql: -------------------------------------------------------------------------------- 1 | -- Modify "job_artefacts" table 2 | ALTER TABLE "public"."job_artefacts" ADD COLUMN "filename" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20241107162605.sql: -------------------------------------------------------------------------------- 1 | -- Modify "github_apps" table 2 | ALTER TABLE "public"."github_apps" ADD COLUMN "client_id" text NULL, ADD COLUMN "client_secret_encrypted" text NULL, ADD COLUMN "webhook_secret_encrypted" text NULL, ADD COLUMN "private_key_encrypted" text NULL, ADD COLUMN "private_key_base64_encrypted" text NULL, ADD COLUMN "org" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20241107163722.sql: -------------------------------------------------------------------------------- 1 | -- Create "github_app_connections" table 2 | CREATE TABLE "public"."github_app_connections" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "github_id" bigint NULL, 8 | "client_id" text NULL, 9 | "client_secret_encrypted" text NULL, 10 | "webhook_secret_encrypted" text NULL, 11 | "private_key_encrypted" text NULL, 12 | "private_key_base64_encrypted" text NULL, 13 | "org" text NULL, 14 | "name" text NULL, 15 | "github_app_url" text NULL, 16 | PRIMARY KEY ("id") 17 | ); 18 | -- Create index "idx_github_app_connections_deleted_at" to table: "github_app_connections" 19 | CREATE INDEX "idx_github_app_connections_deleted_at" ON "public"."github_app_connections" ("deleted_at"); 20 | -- Drop "github_apps" table 21 | DROP TABLE "public"."github_apps"; 22 | -------------------------------------------------------------------------------- /backend/migrations/20241107172343.sql: -------------------------------------------------------------------------------- 1 | -- Modify "github_app_connections" table 2 | ALTER TABLE "public"."github_app_connections" ADD COLUMN "organisation_id" bigint NULL, ADD 3 | CONSTRAINT "fk_github_app_connections_organisation" FOREIGN KEY ("organisation_id") REFERENCES "public"."organisations" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 4 | -------------------------------------------------------------------------------- /backend/migrations/20241114202249.sql: -------------------------------------------------------------------------------- 1 | -- Create "repo_caches" table 2 | CREATE TABLE "public"."repo_caches" ( 3 | "id" bigserial NOT NULL, 4 | "created_at" timestamptz NULL, 5 | "updated_at" timestamptz NULL, 6 | "deleted_at" timestamptz NULL, 7 | "org_id" bigint NULL, 8 | "repo_full_name" text NULL, 9 | "digger_yml_str" text NULL, 10 | "digger_config" bytea NULL, 11 | PRIMARY KEY ("id") 12 | ); 13 | -- Create index "idx_repo_caches_deleted_at" to table: "repo_caches" 14 | CREATE INDEX "idx_repo_caches_deleted_at" ON "public"."repo_caches" ("deleted_at"); 15 | -------------------------------------------------------------------------------- /backend/migrations/20241229112312.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "ai_summary_comment_id" text NULL, ADD COLUMN "report_terraform_outputs" boolean NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250220084846.sql: -------------------------------------------------------------------------------- 1 | -- Modify "users" table 2 | ALTER TABLE "public"."users" ADD COLUMN "email" text NULL, ADD COLUMN "external_id" text NULL, ADD COLUMN "org_id" bigint NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250220172054.sql: -------------------------------------------------------------------------------- 1 | -- Modify "users" table 2 | ALTER TABLE "public"."users" ADD COLUMN "external_source" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250220172321.sql: -------------------------------------------------------------------------------- 1 | -- Create index "idx_user_external_source" to table: "users" 2 | CREATE UNIQUE INDEX "idx_user_external_source" ON "public"."users" ("external_source", "external_id"); 3 | -------------------------------------------------------------------------------- /backend/migrations/20250220173053.sql: -------------------------------------------------------------------------------- 1 | -- Create index "idx_users_email" to table: "users" 2 | CREATE UNIQUE INDEX "idx_users_email" ON "public"."users" ("email"); 3 | -------------------------------------------------------------------------------- /backend/migrations/20250220173439.sql: -------------------------------------------------------------------------------- 1 | -- Rename a column from "org_id" to "organisation_id" 2 | ALTER TABLE "public"."users" RENAME COLUMN "org_id" TO "organisation_id"; 3 | -- Modify "users" table 4 | ALTER TABLE "public"."users" ADD CONSTRAINT "fk_users_organisation" FOREIGN KEY ("organisation_id") REFERENCES "public"."organisations" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 5 | -------------------------------------------------------------------------------- /backend/migrations/20250221044813.sql: -------------------------------------------------------------------------------- 1 | -- Drop index "idx_organisation" from table: "organisations" 2 | DROP INDEX "public"."idx_organisation"; 3 | -- Create index "idx_organisation" to table: "organisations" 4 | CREATE INDEX "idx_organisation" ON "public"."organisations" ("name"); 5 | -------------------------------------------------------------------------------- /backend/migrations/20250224152926.sql: -------------------------------------------------------------------------------- 1 | -- Modify "repos" table 2 | ALTER TABLE "public"."repos" ADD COLUMN "vcs" text NULL DEFAULT 'github'; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250226185150.sql: -------------------------------------------------------------------------------- 1 | -- Modify "github_app_connections" table 2 | ALTER TABLE "public"."github_app_connections" ADD COLUMN "bitbucket_access_token_encrypted" text NULL, ADD COLUMN "bitbucket_webhook_secret_encrypted" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250302190926.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "vcs_connection_id" bigint NULL, ADD CONSTRAINT "fk_digger_batches_vcs_connection" FOREIGN KEY ("vcs_connection_id") REFERENCES "public"."github_app_connections" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250325115901.sql: -------------------------------------------------------------------------------- 1 | -- Modify "github_app_connections" table 2 | ALTER TABLE "public"."github_app_connections" ADD COLUMN "gitlab_access_token_encrypted" text NULL, ADD COLUMN "gitlab_webhook_secret_encrypted" text NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250325134924.sql: -------------------------------------------------------------------------------- 1 | -- Modify "github_app_connections" table 2 | ALTER TABLE "public"."github_app_connections" ADD COLUMN "vcs_type" text NULL DEFAULT 'bitbucket'; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250416152705.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "cover_all_impacted_projects" boolean NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250512172515.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_jobs" table 2 | ALTER TABLE "public"."digger_jobs" ADD COLUMN "pr_comment_id" bigint NULL; 3 | -------------------------------------------------------------------------------- /backend/migrations/20250512213729.sql: -------------------------------------------------------------------------------- 1 | -- Modify "digger_batches" table 2 | ALTER TABLE "public"."digger_batches" ADD COLUMN "created_at" timestamptz NULL, ADD COLUMN "updated_at" timestamptz NULL, ADD COLUMN "deleted_at" timestamptz NULL; 3 | -- Create index "idx_digger_batches_deleted_at" to table: "digger_batches" 4 | CREATE INDEX "idx_digger_batches_deleted_at" ON "public"."digger_batches" ("deleted_at"); 5 | -------------------------------------------------------------------------------- /backend/models/artefact.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "gorm.io/gorm" 5 | ) 6 | 7 | type JobArtefact struct { 8 | gorm.Model 9 | JobTokenID uint 10 | JobToken JobToken 11 | Filename string 12 | Contents []byte `gorm:"type:bytea"` 13 | Size int64 14 | ContentType string 15 | } 16 | -------------------------------------------------------------------------------- /backend/models/cache.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "gorm.io/gorm" 5 | ) 6 | 7 | // storing repo cache such as digger.yml configuration 8 | type RepoCache struct { 9 | gorm.Model 10 | OrgId uint 11 | RepoFullName string 12 | DiggerYmlStr string 13 | DiggerConfig []byte `gorm:"type:bytea"` 14 | } 15 | -------------------------------------------------------------------------------- /backend/models/locking.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "gorm.io/gorm" 4 | 5 | type DiggerLock struct { 6 | gorm.Model 7 | Resource string `gorm:"index:idx_digger_locked_resource"` 8 | LockId int 9 | Organisation *Organisation 10 | OrganisationID uint 11 | } 12 | -------------------------------------------------------------------------------- /backend/models/policies.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "gorm.io/gorm" 4 | 5 | const ( 6 | POLICY_TYPE_ACCESS = "access" 7 | POLICY_TYPE_PLAN = "plan" 8 | POLICY_TYPE_DRIFT = "drift" 9 | ) 10 | 11 | type Policy struct { 12 | gorm.Model 13 | Project *Project 14 | ProjectID *uint 15 | Policy string 16 | Type string 17 | CreatedBy *User 18 | CreatedByID *uint 19 | Organisation *Organisation 20 | OrganisationID uint 21 | Repo *Repo 22 | RepoID *uint 23 | } 24 | -------------------------------------------------------------------------------- /backend/models/setup.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "log/slog" 5 | "os" 6 | 7 | slogGorm "github.com/orandin/slog-gorm" 8 | "gorm.io/driver/postgres" 9 | _ "gorm.io/driver/postgres" 10 | "gorm.io/gorm" 11 | ) 12 | 13 | type Database struct { 14 | GormDB *gorm.DB 15 | } 16 | 17 | var DEFAULT_ORG_NAME = "digger" 18 | 19 | // var DB *gorm.DB 20 | var DB *Database 21 | 22 | func ConnectDatabase() { 23 | database, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{ 24 | Logger: slogGorm.New(), 25 | }) 26 | if err != nil { 27 | slog.Error("Failed to connect to database", "error", err) 28 | panic("Failed to connect to database!") 29 | } 30 | 31 | DB = &Database{GormDB: database} 32 | 33 | // data and fixtures added 34 | orgNumberOne, err := DB.GetOrganisation(DEFAULT_ORG_NAME) 35 | if orgNumberOne == nil { 36 | slog.Info("No default organization found, creating default organisation", "name", DEFAULT_ORG_NAME) 37 | _, err := DB.CreateOrganisation("digger", "", DEFAULT_ORG_NAME) 38 | if err != nil { 39 | slog.Error("Failed to create default organization", "error", err) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /backend/models/user.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "gorm.io/gorm" 4 | 5 | type User struct { 6 | gorm.Model 7 | Email string `gorm:"uniqueIndex"` 8 | ExternalSource string `gorm:"uniqueIndex:idx_user_external_source"` 9 | ExternalId string `gorm:"uniqueIndex:idx_user_external_source"` 10 | // the default org currently in use by this user 11 | OrganisationId *uint 12 | Organisation Organisation 13 | Username string `gorm:"uniqueIndex:idx_user"` 14 | } 15 | -------------------------------------------------------------------------------- /backend/queries/queries.go: -------------------------------------------------------------------------------- 1 | package queries 2 | 3 | import "time" 4 | 5 | type JobQueryResult struct { 6 | ID uint `gorm:"column:id"` 7 | CreatedAt time.Time `gorm:"column:created_at"` 8 | UpdatedAt time.Time `gorm:"column:updated_at"` 9 | DeletedAt *time.Time `gorm:"column:deleted_at"` 10 | DiggerJobID string `gorm:"column:digger_job_id"` 11 | Status string `gorm:"column:status"` 12 | WorkflowRunURL string `gorm:"column:workflow_run_url"` 13 | WorkflowFile string `gorm:"column:workflow_file"` 14 | TerraformOutput string `gorm:"column:terraform_output"` 15 | PRNumber int `gorm:"column:pr_number"` 16 | RepoFullName string `gorm:"column:repo_full_name"` 17 | BranchName string `gorm:"column:branch_name"` 18 | } 19 | -------------------------------------------------------------------------------- /backend/scripts/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [[ -z "${BASELINE_MIGRATION}" ]]; then 5 | cd /app 6 | if [[ "${ALLOW_DIRTY}" == "true" ]]; then 7 | atlas migrate apply --url $DATABASE_URL --allow-dirty 8 | else 9 | atlas migrate apply --url $DATABASE_URL 10 | fi 11 | ./backend 12 | else 13 | cd /app 14 | atlas migrate apply --url $DATABASE_URL --baseline $BASELINE_MIGRATION 15 | ./backend 16 | fi -------------------------------------------------------------------------------- /backend/sql/migration_25_08_2023.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO public.repos 2 | SELECT id, created_at, updated_at, deleted_at, name, organisation_id 3 | FROM public.namespaces; 4 | 5 | UPDATE public.projects 6 | SET repo_id = namespace_id; 7 | 8 | UPDATE public.policies 9 | SET repo_id = namespace_id; 10 | -------------------------------------------------------------------------------- /backend/tasks/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | tasks 3 | -------------------------------------------------------------------------------- /backend/templates/github_success.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |You can now close this tab.
15 |