diff --git a/docs/admin/config.rst b/docs/admin/config.rst index c2b5a3c9ce0e..4b7f0e320126 100644 --- a/docs/admin/config.rst +++ b/docs/admin/config.rst @@ -831,6 +831,33 @@ List for credentials for Bitbucket servers. :ref:`vcs-bitbucket-server`, `Bitbucket: HTTP access token `_ +.. setting:: DEVOPS_CREDENTIALS + +DEVOPS_CREDENTIALS +------------------ + +.. versionadded:: 5.2 + +List for credentials for Azure DevOps servers. + +.. code-block:: python + + DEVOPS_CREDENTIALS = { + "dev.azure.com": { + "username": "project-name", + "token": "your-api-token", + "organization": "organization-name", + }, + } + +.. include:: /snippets/vcs-credentials-devops.rst + +.. seealso:: + + :ref:`vcs-devops`, + `DevOps: Personal access token `_ + + .. setting:: GOOGLE_ANALYTICS_ID GOOGLE_ANALYTICS_ID @@ -1783,7 +1810,8 @@ VCS_API_DELAY .. versionadded:: 4.15.1 Configures minimal delay in seconds between third-party API calls in -:ref:`vcs-github`, :ref:`vcs-gitlab`, :ref:`vcs-gitea`, and :ref:`vcs-pagure`. +:ref:`vcs-github`, :ref:`vcs-gitlab`, :ref:`vcs-gitea`, :ref:`vcs-pagure`, and +:ref:`vcs-devops`. This rate-limits API calls from Weblate to these services to avoid overloading them. diff --git a/docs/admin/continuous.rst b/docs/admin/continuous.rst index 682ce1ddb961..302cd30673bd 100644 --- a/docs/admin/continuous.rst +++ b/docs/admin/continuous.rst @@ -276,12 +276,13 @@ under :guilabel:`Repository maintenance` or using API via :option:`wlc push`. The push options differ based on the :ref:`vcs` used, more details are found in that chapter. In case you do not want direct pushes by Weblate, there is support for -:ref:`vcs-github`, :ref:`vcs-gitlab`, :ref:`vcs-gitea`, :ref:`vcs-pagure` pull requests or -:ref:`vcs-gerrit` reviews, you can activate these by choosing -:guilabel:`GitHub`, :guilabel:`GitLab`, :guilabel:`Gitea`, :guilabel:`Gerrit` or -:guilabel:`Pagure` as :ref:`component-vcs` in :ref:`component`. +:ref:`vcs-github`, :ref:`vcs-gitlab`, :ref:`vcs-gitea`, :ref:`vcs-pagure`, :ref`vcs-devops` +pull requests or :ref:`vcs-gerrit` reviews, you can activate these by choosing +:guilabel:`GitHub`, :guilabel:`GitLab`, :guilabel:`Gitea`, :guilabel:`Gerrit`, +:guilabel:`DevOps`, or :guilabel:`Pagure` as :ref:`component-vcs` in :ref:`component`. -Overall, following options are available with Git, GitHub and GitLab: +Overall, following options are available with Git, Mercurial, GitHub, GitLab, +Gitea, Pagure, and DevOps: +-----------------------------------+-------------------------------+-------------------------------+-------------------------------+ | Desired setup | :ref:`component-vcs` | :ref:`component-push` | :ref:`component-push_branch` | @@ -314,6 +315,10 @@ Overall, following options are available with Git, GitHub and GitLab: +-----------------------------------+-------------------------------+-------------------------------+-------------------------------+ | Pagure merge request from branch | :ref:`vcs-pagure` | SSH URL [#empty]_ | Branch name | +-----------------------------------+-------------------------------+-------------------------------+-------------------------------+ +| DevOps pull request from fork | :ref:`vcs-devops` | `empty` | `empty` | ++-----------------------------------+-------------------------------+-------------------------------+-------------------------------+ +| DevOps pull request from branch | :ref:`vcs-devops` | SSH URL [#empty]_ | Branch name | ++-----------------------------------+-------------------------------+-------------------------------+-------------------------------+ .. [#empty] Can be empty in case :ref:`component-repo` supports pushing. diff --git a/docs/admin/install/docker.rst b/docs/admin/install/docker.rst index 72bbe6bd1ecc..273cd6167d2b 100644 --- a/docs/admin/install/docker.rst +++ b/docs/admin/install/docker.rst @@ -787,6 +787,30 @@ Generic settings :ref:`vcs-gitlab` +.. envvar:: WEBLATE_DEVOPS_USERNAME +.. envvar:: WEBLATE_DEVOPS_TOKEN +.. envvar:: WEBLATE_DEVOPS_HOST +.. envvar:: WEBLATE_DEVOPS_ORGANIZATION +.. envvar:: WEBLATE_DEVOPS_CREDENTIALS + + Configures DevOps pull-requests integration by changing + :setting:`DEVOPS_CREDENTIALS`. + + **Example:** + + .. code-block:: sh + + WEBLATE_DEVOPS_USERNAME=project-name + WEBLATE_DEVOPS_HOST=dev.azure.com + WEBLATE_DEVOPS_TOKEN=api-token + WEBLATE_DEVOPS_ORGANIZATION=org-name + # or as a Python dictionary + WEBLATE_DEVOPS_CREDENTIALS='{ "dev.azure.com": { "username": "project-name", "token": "api-token", "organization": "org-name" } }' + + .. seealso:: + + :ref:`vcs-devops` + .. envvar:: WEBLATE_GITEA_USERNAME .. envvar:: WEBLATE_GITEA_TOKEN .. envvar:: WEBLATE_GITEA_HOST diff --git a/docs/snippets/vcs-credentials-devops.rst b/docs/snippets/vcs-credentials-devops.rst new file mode 100644 index 000000000000..eea353919214 --- /dev/null +++ b/docs/snippets/vcs-credentials-devops.rst @@ -0,0 +1,59 @@ +The configuration dictionary consists of credentials defined for each API host. +The API host might be different from what you use in the web browser, for +example GitHub API is accessed as ``api.github.com``. + +The following configuration is available for each host: + +``username`` + The name of the DevOps project. This is not the repository name. +``organization`` + The name of the organization of the project. +``workItemIds`` + An optional list of work items IDs from your organization. When provided + new pull requests will have these attached. +``token`` + API token for the API user, required. +``scheme`` + .. versionadded:: 4.18 + + Scheme override. Weblate attempts to parse scheme from the repository URL + and falls backs to ``https``. If you are running the API server internally, + you might want to use ``http`` instead, but consider security. + +.. hint:: + + In the Docker container, the credentials can be configured in four variables + and the credentials are built out of that. An example configuration might + look like: + + .. code-block:: shell + + WEBLATE_DEVOPS_USERNAME=project-name + WEBLATE_DEVOPS_ORGANIZATION=org-name + WEBLATE_DEVOPS_TOKEN=api-token + WEBLATE_DEVOPS_HOST=dev.azure.com + + Will be used as: + + .. code-block:: python + + DEVOPS_CREDENTIALS = { + "dev.azure.com": { + "username": "project-name", + "token": "api-token", + "organization": "org-name", + } + } + + Alternatively the Python dictionary can be provided as a string: + + .. code-block:: shell + + WEBLATE_DEVOPS_CREDENTIALS='{ "dev.azure.com": { "username": "project-name", "token": "api-token", "organization": "org-name" } }' + + Or the path to a file containing the Python dictionary: + + .. code-block:: shell + + echo '{ "dev.azure.com": { "username": "project-name", "token": "api-token", "organization": "org-name" } }' > /path/to/devops-credentials + WEBLATE_DEVOPS_CREDENTIALS_FILE='/path/to/devops-credentials' diff --git a/docs/vcs.rst b/docs/vcs.rst index b6944549b6fb..27eac889a36b 100644 --- a/docs/vcs.rst +++ b/docs/vcs.rst @@ -5,8 +5,8 @@ Version control integration Weblate currently supports :ref:`vcs-git` (with extended support for :ref:`vcs-github`, :ref:`vcs-gitlab`, :ref:`vcs-gitea`, :ref:`vcs-gerrit`, -:ref:`vcs-git-svn` and :ref:`vcs-bitbucket-server`) and :ref:`vcs-mercurial` as -version control back-ends. +:ref:`vcs-git-svn`, :ref:`vcs-bitbucket-server`, and :ref`vss-devops`) and +:ref:`vcs-mercurial` as version control back-ends. .. _vcs-repos: @@ -423,6 +423,30 @@ pushing them directly to the repository. The Gerrit documentation has the details on the configuration necessary to set up such repositories. +.. _vcs-devops: +.. _devops-push: + +DevOps pull requests +-------------------- + +This adds a thin layer atop :ref:`vcs-git` using the `DevOps API`_ to allow pushing +translation changes as pull requests, instead of pushing directly to the repository. + +:ref:`vcs-git` pushes changes directly to a repository, while +:ref:`vcs-devops` creates pull requests. +The latter is not needed for merely accessing Git repositories. + +You need to configure API credentials (:setting:`DEVOPS_CREDENTIALS`) in the +Weblate settings to make this work. Once configured, you will see a +:guilabel:`DevOps` option when selecting :ref:`component-vcs`. + +.. seealso:: + + :ref:`push-changes`, + :setting:`DEVOPS_CREDENTIALS` + +.. _DevOps API: https://learn.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-7.2 + .. _git-review: https://pypi.org/project/git-review/ .. _vcs-mercurial: diff --git a/weblate/utils/environment.py b/weblate/utils/environment.py index 875c41cb0d92..e7e450491491 100644 --- a/weblate/utils/environment.py +++ b/weblate/utils/environment.py @@ -91,8 +91,8 @@ def get_env_credentials( name: str, ) -> dict[str, dict[str, str]]: """Parses VCS integration credentials.""" - if credentials := get_env_str(f"WEBLATE_{name}_CREDENTIALS"): - return ast.literal_eval(credentials) + if found_env_credentials := get_env_str(f"WEBLATE_{name}_CREDENTIALS"): + return ast.literal_eval(found_env_credentials) username = os.environ.get(f"WEBLATE_{name}_USERNAME") token = os.environ.get(f"WEBLATE_{name}_TOKEN") host = os.environ.get(f"WEBLATE_{name}_HOST") diff --git a/weblate/vcs/git.py b/weblate/vcs/git.py index 87bd2b6203bd..c04371b6ddd3 100644 --- a/weblate/vcs/git.py +++ b/weblate/vcs/git.py @@ -1134,7 +1134,7 @@ def parse_repo_url(self, repo: str | None = None) -> tuple[str, str, str, str]: (scheme, host, owner, slug) = super().parse_repo_url(repo) - # ssh links are in the subdomain "ssh.", the API link doesn't have that, so remove it + # ssh links are in a subdomain, the API link doesn't have that so remove it if host.startswith("ssh."): host = host[len("ssh.") :] @@ -1305,7 +1305,7 @@ def __get_forks(self, credentials: dict) -> list: def __get_org_id(self) -> str: credentials = self.get_credentials() - org = credentials.get("owner").split("/")[0] # format is "org/proj" + org = credentials["owner"].split("/")[0] # format is "org/proj" url = self.ORG_API_TEMPLATE.format( scheme=credentials["scheme"],