Skip to content

Commit

Permalink
Merge branch 'develop' into bugfix/collect_user_name_correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
kalisp authored Nov 5, 2024
2 parents 6c7b9b1 + e6e1d4c commit c5eb2b7
Show file tree
Hide file tree
Showing 30 changed files with 316 additions and 111 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/deploy_docker_images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: 🐳 Docker Image Deployment

on:
workflow_dispatch:
release:
types: [published]

jobs:
build:
name: Push docker images to docker hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build service images
id: build-docker-images
run: make build-all SERVICE=leecher -C ./services

- name: Push service images
id: push-docker-images
run: make dist-all SERVICE=leecher -C ./services
24 changes: 24 additions & 0 deletions .github/workflows/pr_linting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: 📇 Code Linting

on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]

workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number}}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write

jobs:
linting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
25 changes: 25 additions & 0 deletions .github/workflows/release_trigger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: 🚀 Release Trigger

on:
workflow_dispatch:
inputs:
draft:
type: boolean
description: "Create Release Draft"
required: false
default: false
release_overwrite:
type: string
description: "Set Version Release Tag"
required: false

jobs:
call-release-trigger:
uses: ynput/ops-repo-automation/.github/workflows/release_trigger.yml@main
with:
draft: ${{ inputs.draft }}
release_overwrite: ${{ inputs.release_overwrite }}
secrets:
token: ${{ secrets.YNPUT_BOT_TOKEN }}
email: ${{ secrets.CI_EMAIL }}
user: ${{ secrets.CI_USER }}
16 changes: 16 additions & 0 deletions .github/workflows/upload_to_ynput_cloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: 📤 Upload to Ynput Cloud

on:
workflow_dispatch:
release:
types: [published]

jobs:
call-upload-to-ynput-cloud:
uses: ynput/ops-repo-automation/.github/workflows/upload_to_ynput_cloud.yml@main
secrets:
CI_EMAIL: ${{ secrets.CI_EMAIL }}
CI_USER: ${{ secrets.CI_USER }}
YNPUT_BOT_TOKEN: ${{ secrets.YNPUT_BOT_TOKEN }}
YNPUT_CLOUD_URL: ${{ secrets.YNPUT_CLOUD_URL }}
YNPUT_CLOUD_TOKEN: ${{ secrets.YNPUT_CLOUD_TOKEN }}
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Shotgrid integration for Ayon
# Shotgrid integration for AYON

This project provides three elements for the Ayon pipeline:
* server/ - The Ayon Backend Addon.
This project provides three elements for the AYON pipeline:
* server/ - The AYON Backend Addon.
* frontend/ - The AYON server Shotgrid settings tab.
* client/ - The AYON desktop integration.
* services/ - Standalone dockerized daemons that act based on events (aka `leecher` and `processors`).
Expand All @@ -22,7 +22,7 @@ We can now go into the `Settings > Studio settings > Shotgrid` page in AYON and


## Desktop application
When launching Ayon for the first time you'll be asked to provide a login (only the username) for Shotgrid, this is the user that will be used for publishing.
When launching AYON for the first time you'll be asked to provide a login (only the username) for Shotgrid, this is the user that will be used for publishing.
After providing a login people can publish normally, the integartion will ensure that the user can connect to Shotgrid, that has the correct permissions and will create the Version and PublishedFile in Shotgrid if the publish is succesful.

## Services
Expand All @@ -35,7 +35,7 @@ The three provided services are:
* `leecher` - Periodically queries the `EventLogEntry` table on Shotgrid and ingests any event that interests us dispatching it as a `shotgrid.event`, this will only query projects that have the "Ayon Auto Sync" field enabled.
* `transmitter` - Periodically check for new events in AYON of topic `entity.*`, and push any changes to Shotgrid, only affects to projects that have the "Ayon Auto Sync" field enabled.

The most straighforward way to get this up and running is by using ASH (Ayon Service Host), after loading the Addon on the server, you should be able to spawn services in the "Services" page.
The most straighforward way to get this up and running is by using ASH (AYON Service Host), after loading the Addon on the server, you should be able to spawn services in the "Services" page.

### Development
There's a single `Makefile` at the root of the `services` folder, which is used to `build` the docker images and to run the services locally with the `dev` target, this is UNIX only for the time being, running `make` without argument will print information as to how to run use it.
Expand All @@ -46,7 +46,7 @@ To build the docker images you can run `make SERVICE=<service-name> build`, so f
#### Running the Service locally
In order to run the service locally we need to specify certain environment variables, to do so, copy the `sample_env` file, rename to `.env` and fill the fields acordingly:
```
AYON_API_KEY=<AYON_API_KEY> # You can create a `service` user in Ayon, and then get the Key from there.
AYON_API_KEY=<AYON_API_KEY> # You can create a `service` user in AYON, and then get the Key from there.
AYON_SERVER_URL=<YOUR_AYON_URL>
PYTHONDONTWRITEBYTECODE=1
```
Expand All @@ -60,7 +60,7 @@ You should now see something similar to:
```sh
INFO Initializing the Shotgrid Processor.
DEBUG Found these handlers: {'create-project': [<module 'project_sync'>], 'sync-from-shotgrid': [<module 'sync_from_shotgrid'>], 'shotgrid-event': [<module 'update_from_shotgrid'>]}
INFO Start enrolling for Ayon `shotgrid.event` Events...
INFO Start enrolling for AYON `shotgrid.event` Events...
INFO Querying for new `shotgrid.event` events...
INFO No event of origin `shotgrid.event` is pending.
```
Expand Down
2 changes: 1 addition & 1 deletion client/ayon_shotgrid/lib/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def save_local_login(username, password):
reg = AYONSecureRegistry("shotgrid/user")
reg.set_item("value", username)
reg = AYONSecureRegistry("shotgrid/pass")
reg.set_item("value", password)
reg.set_item("value", password or "")


def clear_local_login():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class IntegrateShotgridVersion(pyblish.api.InstancePlugin):
label = "Shotgrid Version"

# Dictionary of SG fields we want to update that map to other fields in the
# Ayon entity
# AYON entity
fields_to_add = {
"comment": (str, "description"),
"productType": (str, "sg_version_type"),
Expand Down Expand Up @@ -176,7 +176,7 @@ def process(self, instance):
"Instance doesn't have a 'versionEntity' to extract the id."
)
version_id = "-"
data_to_update["sg_ayon_id"] = version_id
data_to_update["sg_ayon_id"] = str(version_id)

self.log.info(f"Updating Shotgrid version with {data_to_update}")
sg_session.update("Version", sg_version["id"], data_to_update)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def process(self, context):
if not (user_login and sg_session and sg_project):
raise PublishValidationError("Missing Shotgrid Credentials")

self.log.info("Login ShotGrid set in Ayon is {}".format(user_login))
self.log.info("Login ShotGrid set in AYON is {}".format(user_login))
self.log.info("Current ShotGrid Project is {}".format(sg_project))

sg_user = sg_session.find_one(
Expand Down
3 changes: 2 additions & 1 deletion client/ayon_shotgrid/tray/sg_login_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self, addon, parent=None):
self.login_type = self.addon.get_client_login_type()

self.setWindowTitle("Ayon - Shotgrid Login")

icon = QtGui.QIcon(resources.get_ayon_icon_filepath())
self.setWindowIcon(icon)

Expand All @@ -44,7 +45,7 @@ def setup_ui(self):
server_url = self.addon.get_sg_url()

if not server_url:
server_url = "No Shotgrid Server set in Ayon Settings."
server_url = "No Shotgrid Server set in AYON Settings."

sg_server_url_label = QtWidgets.QLabel(
"Please provide the credentials to log in into the "
Expand Down
8 changes: 4 additions & 4 deletions client/ayon_shotgrid/tray/shotgrid_tray.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class ShotgridTrayWrapper:
""" Shotgrid menu entry for the Ayon tray.
""" Shotgrid menu entry for the AYON tray.
Displays the Shotgrid URL specified in the Server Addon Settings and
allows the person to set a username to be used with the API.
Expand All @@ -21,7 +21,7 @@ def __init__(self, addon):
server_url = self.addon.get_sg_url()

if not server_url:
server_url = "No Shotgrid Server set in Ayon Settings."
server_url = "No Shotgrid Server set in AYON Settings."

self.sg_server_label = QtWidgets.QAction("Server: {0}".format(
server_url
Expand All @@ -45,13 +45,13 @@ def show_sg_username_dialog(self):
self.sg_username_dialog.raise_()

def tray_menu(self, tray_menu):
"""Add Shotgrid Submenu to Ayon tray.
"""Add Shotgrid Submenu to AYON tray.
A non-actionable action displays the Shotgrid URL and the other
action allows the person to set and check their Shotgrid username.
Args:
tray_menu (QtWidgets.QMenu): The Ayon Tray menu.
tray_menu (QtWidgets.QMenu): The AYON Tray menu.
"""
shotgrid_tray_menu = QtWidgets.QMenu("Shotgrid", tray_menu)
shotgrid_tray_menu.addAction(self.sg_server_label)
Expand Down
2 changes: 1 addition & 1 deletion client/ayon_shotgrid/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring shotgrid addon version."""
__version__ = "0.4.5-dev.1"
__version__ = "0.4.6+dev"
35 changes: 29 additions & 6 deletions create_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ def create_server_package(current_dir, output_dir, addon_output_dir, log):
log.info(f"Output package can be found: {output_path}")


def _propagate_version(current_dir):
# Update client version file with version from 'package.py'
client_version_file = os.path.join(
current_dir, "client", ADDON_CLIENT_DIR, "version.py"
)
with open(client_version_file, "w") as stream:
stream.write(
CLIENT_VERSION_CONTENT.format(ADDON_NAME, ADDON_VERSION)
)

# Update version in services pyproject.toml files
for service in ("leecher", "processor", "transmitter"):
service_pyproject_path = os.path.join(
current_dir, "services", f"{service}/pyproject.toml"
)
new_lines = []
with open(service_pyproject_path, "r") as stream:
version_found = False
for line in stream.readlines():
if not version_found and line.startswith("version"):
line = f'version = "{ADDON_VERSION}"\n'
version_found = True
new_lines.append(line)

with open(service_pyproject_path, "w") as stream:
stream.write("".join(new_lines))


def main(
output_dir: Optional[str] = None,
skip_zip: bool = False,
Expand All @@ -277,12 +305,7 @@ def main(
if not output_dir:
output_dir = os.path.join(current_dir, "package")

# Update client version file with version from 'package.py'
client_version_file = os.path.join(
current_dir, "client", ADDON_CLIENT_DIR, "version.py"
)
with open(client_version_file, "w") as stream:
stream.write(CLIENT_VERSION_CONTENT.format(ADDON_NAME, ADDON_VERSION))
_propagate_version(current_dir)

addon_output_root = os.path.join(output_dir, ADDON_NAME)
addon_output_dir = os.path.join(addon_output_root, ADDON_VERSION)
Expand Down
2 changes: 1 addition & 1 deletion package.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "shotgrid"
title = "Shotgrid"
version = "0.4.5-dev.1"
version = "0.4.6+dev"
client_dir = "ayon_shotgrid"

services = {
Expand Down
74 changes: 74 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]

# Same as Black.
line-length = 79
indent-width = 4

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F", "W"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false

# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"
2 changes: 1 addition & 1 deletion server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async def setup(self):
self.request_server_restart()

async def create_shotgrid_attributes(self) -> bool:
"""Make sure Ayon has the `shotgridId` and `shotgridPath` attributes.
"""Make sure AYON has the `shotgridId` and `shotgridPath` attributes.
Returns:
bool: 'True' if an attribute was created or updated.
Expand Down
Loading

0 comments on commit c5eb2b7

Please sign in to comment.