Skip to content

Commit

Permalink
allow testing of Jira Cloud (pycontribs#1107)
Browse files Browse the repository at this point in the history
* initial attempt of a Jira Cloud github action

* reusable workflows to enforce Server passing before Cloud

* add opt-in marker for running tests on jira cloud `@allow_on_cloud`

* fixes to allow Cloud tests to run
update error handling in JiraTestManager, remove default flaky

* use property access to `is_jira_cloud_ci`

* `create_project()` leadAccountId inline

* fix bugs in setting defaults for create_project

* set default project template for Cloud correctly

* `test_group()` `@allow_on_cloud`

* update exception handling to use `JIRAError` over Exception where possible

* add docstring to `_project_exists()`
  • Loading branch information
adehad authored and svermeulen committed Oct 31, 2021
1 parent f2a2d49 commit 8d6a171
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 148 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/jira_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Jira CI

on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main
pull_request:
branches:
- main

jobs:
Server:
uses: pycontribs/jira/.github/workflows/jira_server_ci.yml@main

Cloud:
needs: Server
uses: pycontribs/jira/.github/workflows/jira_cloud_ci.yml@main
secrets:
CLOUD_ADMIN: ${{ secrets.CI_JIRA_CLOUD_ADMIN }}
CLOUD_ADMIN_TOKEN: ${{ secrets.CI_JIRA_CLOUD_ADMIN_TOKEN }}
CLOUD_USER: ${{ secrets.CI_JIRA_CLOUD_USER }}
CLOUD_USER_TOKEN: ${{ secrets.CI_JIRA_CLOUD_USER_TOKEN }}
70 changes: 70 additions & 0 deletions .github/workflows/jira_cloud_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Jira Cloud CI

on:
workflow_call:
secrets:
CLOUD_ADMIN:
required: true
CLOUD_ADMIN_TOKEN:
required: true
CLOUD_USER:
required: true
CLOUD_USER_TOKEN:
required: true
workflow_dispatch:

jobs:
test:
name: ${{ matrix.os }} / Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}-latest
strategy:
matrix:
os: [Ubuntu]
# We only test a single version to prevent concurrent
# running of tests influencing one another
python-version: [3.8]

steps:
- uses: actions/checkout@master

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Get pip cache dir
id: pip-cache
run: |
echo "::set-output name=dir::$(pip cache dir)"
- name: Setup the Pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: >-
${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }}-${{
hashFiles('setup.py') }}-${{ hashFiles('tox.ini') }}-${{
hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Install Dependencies
run: |
sudo apt-get update; sudo apt-get install gcc libkrb5-dev
python -m pip install --upgrade pip
python -m pip install --upgrade tox tox-gh-actions
- name: Test with tox
run: tox -e py38 -- -m allow_on_cloud
env:
CI_JIRA_TYPE: CLOUD
CI_JIRA_CLOUD_ADMIN: ${{ secrets.CLOUD_ADMIN }}
CI_JIRA_CLOUD_ADMIN_TOKEN: ${{ secrets.CLOUD_ADMIN_TOKEN }}
CI_JIRA_CLOUD_USER: ${{ secrets.CLOUD_USER }}
CI_JIRA_CLOUD_USER_TOKEN: ${{ secrets.CLOUD_USER_TOKEN }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1.0.15
with:
file: ./coverage.xml
name: ${{ runner.os }}-${{ matrix.python-version }}-Cloud
10 changes: 2 additions & 8 deletions .github/workflows/jira_server_ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
name: Jira Server CI

on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches:
- main
pull_request:
branches:
- main
workflow_call:
workflow_dispatch:

jobs:
test:
Expand Down
34 changes: 21 additions & 13 deletions jira/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3790,10 +3790,14 @@ def backup_download(self, filename: str = None):
self.log.error(ioe)
return None

def current_user(self, field: str = "key") -> str:
def current_user(self, field: Optional[str] = None) -> str:
"""Returns the username or emailAddress of the current user. For anonymous
users it will return a value that evaluates as False.
Args:
field (Optional[str]): the name of the identifier field.
Defaults to "accountId" for Jira Cloud, else "key"
Returns:
str
"""
Expand All @@ -3805,6 +3809,9 @@ def current_user(self, field: str = "key") -> str:
r_json: Dict[str, str] = json_loads(r)
self._myself = r_json

if field is None:
field = "accountId" if self._is_cloud else "key"

return self._myself[field]

def delete_project(self, pid: Union[str, Project]) -> Optional[bool]:
Expand Down Expand Up @@ -4015,31 +4022,31 @@ def create_project(

ps_list: List[Dict[str, Any]]

if not permissionScheme:
if permissionScheme is None:
ps_list = self.permissionschemes()
for sec in ps_list:
if sec["name"] == "Default Permission Scheme":
permissionScheme = sec["id"]
break
if not permissionScheme:
break
if permissionScheme is None and ps_list:
permissionScheme = ps_list[0]["id"]

if not issueSecurityScheme:
if issueSecurityScheme is None:
ps_list = self.issuesecurityschemes()
for sec in ps_list:
if sec["name"] == "Default": # no idea which one is default
issueSecurityScheme = sec["id"]
break
if not issueSecurityScheme and ps_list:
break
if issueSecurityScheme is None and ps_list:
issueSecurityScheme = ps_list[0]["id"]

if not projectCategory:
if projectCategory is None:
ps_list = self.projectcategories()
for sec in ps_list:
if sec["name"] == "Default": # no idea which one is default
projectCategory = sec["id"]
break
if not projectCategory and ps_list:
break
if projectCategory is None and ps_list:
projectCategory = ps_list[0]["id"]
# <beep> Atlassian for failing to provide an API to get projectTemplateKey values
# Possible values are just hardcoded and obviously depending on Jira version.
Expand All @@ -4049,7 +4056,9 @@ def create_project(
if not template_name:
# https://confluence.atlassian.com/jirakb/creating-projects-via-rest-api-in-jira-963651978.html
template_key = (
"com.pyxis.greenhopper.jira:basic-software-development-template"
"com.pyxis.greenhopper.jira:gh-simplified-basic"
if self._is_cloud
else "com.pyxis.greenhopper.jira:basic-software-development-template"
)

# https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-projects/#api-rest-api-2-project-get
Expand Down Expand Up @@ -4112,8 +4121,7 @@ def create_project(
"key": key,
"projectTypeKey": ptype,
"projectTemplateKey": template_key,
"lead": assignee,
# "leadAccountId": assignee,
"leadAccountId" if self._is_cloud else "lead": assignee,
"assigneeType": "PROJECT_LEAD",
"description": "",
# "avatarId": 13946,
Expand Down
5 changes: 5 additions & 0 deletions make_local_jira_user.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Attempts to create a test user,
as the empty JIRA instance isn't provisioned with one.
"""
import sys
import time
from os import environ

Expand Down Expand Up @@ -29,6 +30,10 @@ def add_user_to_jira():


if __name__ == "__main__":
if environ.get("CI_JIRA_TYPE", "Server").upper() == "CLOUD":
print("Do not need to create a user for Jira Cloud CI, quitting.")
sys.exit()

start_time = time.time()
timeout_mins = 15
print(
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,8 @@ timeout = 80
filterwarnings =
ignore::pytest.PytestWarning

markers =
allow_on_cloud: opt in for the test to run on Jira Cloud

[mypy]
python_version = 3.6
Loading

0 comments on commit 8d6a171

Please sign in to comment.