Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/deploy-studio-release-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Deploy Studio Release Server

on:
workflow_dispatch:

permissions:
contents: read

jobs:
deploy:
if: >-
github.repository == 'volcengine/veadk-python' &&
github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 30
environment: studio-release
env:
VOLCENGINE_ACCESS_KEY: ${{ secrets.VOLCENGINE_ACCESS_KEY }}
VOLCENGINE_SECRET_KEY: ${{ secrets.VOLCENGINE_SECRET_KEY }}
STUDIO_RELEASE_SERVER_API_KEY: ${{ secrets.STUDIO_RELEASE_SERVER_API_KEY }}

steps:
- name: Check out deployment source
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Set up uv
uses: astral-sh/setup-uv@v6

- name: Deploy release server
run: frontend/service/studio_release_server/deploy.sh --skip-github-secrets
15 changes: 14 additions & 1 deletion frontend/service/studio_release_server/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,19 @@ def _set_github_secret(name: str, value: str) -> None:
raise RuntimeError(f"Could not set GitHub secret {name}: {completed.stderr}")


def _deployment_api_key(*, skip_github_secrets: bool) -> str:
"""Reuse the configured API key when repository secrets stay unchanged."""
if not skip_github_secrets:
return secrets.token_urlsafe(48)
api_key = os.getenv("STUDIO_RELEASE_SERVER_API_KEY", "").strip()
if len(api_key) < 32:
raise ValueError(
"STUDIO_RELEASE_SERVER_API_KEY must be provided when GitHub "
"Secrets are not updated."
)
return api_key


def _parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--source-root", type=Path, default=Path.cwd())
Expand All @@ -550,7 +563,7 @@ def main() -> None:
if not args.skip_github_secrets:
_validate_github_secret_access()
role_trn = _ensure_runtime_role(access_key, secret_key)
api_key = secrets.token_urlsafe(48)
api_key = _deployment_api_key(skip_github_secrets=args.skip_github_secrets)
endpoint, app_id, function_id = _deploy(source_root, api_key, role_trn)
_wait_for_health(endpoint, api_key)
if not args.skip_github_secrets:
Expand Down
29 changes: 29 additions & 0 deletions tests/test_studio_release_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,35 @@ def _run(command: list[str], **kwargs: Any) -> subprocess.CompletedProcess[str]:
]


def test_skip_github_secrets_reuses_existing_api_key(
monkeypatch: pytest.MonkeyPatch,
) -> None:
api_key = "existing-release-key-with-at-least-thirty-two-characters"
monkeypatch.setenv("STUDIO_RELEASE_SERVER_API_KEY", api_key)

assert release_deploy._deployment_api_key(skip_github_secrets=True) == api_key


def test_skip_github_secrets_requires_existing_api_key(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.delenv("STUDIO_RELEASE_SERVER_API_KEY", raising=False)

with pytest.raises(ValueError, match="STUDIO_RELEASE_SERVER_API_KEY"):
release_deploy._deployment_api_key(skip_github_secrets=True)


def test_release_server_deploy_workflow_preserves_api_key() -> None:
workflow = (
Path(__file__).parents[1]
/ ".github/workflows/deploy-studio-release-server.yaml"
).read_text(encoding="utf-8")

assert "workflow_dispatch:" in workflow
assert "secrets.STUDIO_RELEASE_SERVER_API_KEY" in workflow
assert "deploy.sh --skip-github-secrets" in workflow


def test_release_server_readiness_uses_rotated_api_key(
monkeypatch: pytest.MonkeyPatch,
) -> None:
Expand Down
Loading