Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a850b00
refactor: streamline OpenStack options and remove deprecated token_al…
yanksyoon Nov 21, 2025
3ef26d0
chore: update integration test environment variables for OpenStack
yanksyoon Nov 21, 2025
2ffb626
chore: apply pflake8 rules to all tests
yanksyoon Nov 21, 2025
0e7133d
chore: remove reference to unused env var
yanksyoon Nov 21, 2025
305f881
test: map INTEGRATION_TOKEN env var to --token default value
yanksyoon Nov 21, 2025
27a4ded
test: remove unused --token-alt
yanksyoon Nov 21, 2025
c3a900f
test: move option parsing to upper module
yanksyoon Nov 21, 2025
9199b64
chore: update integration test arguments and enhance CI setup guideli…
yanksyoon Nov 21, 2025
6e8d7d7
chore: fix vale complaints
yanksyoon Nov 21, 2025
e32cbc0
chore: minor lint & doc fixes
yanksyoon Nov 21, 2025
4cbfb03
ci: parse repository settings non-sensitive secrets
yanksyoon Nov 21, 2025
f7bd449
ci: trigger w/ new secrets
yanksyoon Nov 23, 2025
e250638
ci: test secret variable conversion
yanksyoon Nov 24, 2025
214dde2
ci: replace sercrets to vars
yanksyoon Nov 24, 2025
04e19f5
ci: test vars settings
yanksyoon Nov 24, 2025
a820122
ci: revert test vars settings
yanksyoon Nov 24, 2025
bef1db1
ci: don't use test image/flavor
yanksyoon Nov 24, 2025
d5829ed
ci: trigger w/ new secrets
yanksyoon Nov 24, 2025
aa477b2
ci: trigger w/ new secrets
yanksyoon Nov 24, 2025
996a3a6
Merge branch 'main' into chore/cleanup-tests
yanksyoon Nov 24, 2025
d99f30b
docs: clarify sensitive values mapping in CONTRIBUTING.md
yanksyoon Nov 24, 2025
79397dd
Merge branch 'chore/cleanup-tests' of https://github.com/canonical/gi…
yanksyoon Nov 24, 2025
5d1f6ff
chore: update to newer platforms syntax for charmcraft yaml
yanksyoon Nov 24, 2025
e94667f
chore: use single OS_ prefixed params for tests
yanksyoon Nov 24, 2025
dea5e71
chore: remove unused vars
yanksyoon Nov 24, 2025
668d30b
chore: revert series deploy fixtures
yanksyoon Nov 24, 2025
d09fc04
chore: revert series deploy fixtures
yanksyoon Nov 24, 2025
dbfcecf
chore: remove ref to openstack clouds yaml fixture
yanksyoon Nov 24, 2025
e3509b2
chore: use VM virt type to mitigate snap bug
yanksyoon Nov 24, 2025
edc5bd1
debug
yanksyoon Nov 24, 2025
7842775
test: use matching series
yanksyoon Nov 24, 2025
d930d77
test: update path to str
yanksyoon Nov 24, 2025
eb538b1
test: debug series
yanksyoon Nov 24, 2025
bd0dbe9
chore: latest charmcraft syntax
yanksyoon Nov 24, 2025
c38c983
chore: latest charmcraft syntax
yanksyoon Nov 24, 2025
5f8395e
chore: image builder set vm constraints
yanksyoon Nov 24, 2025
249cc78
test: only deploy jammy (deprecated ops library charm base detection)
yanksyoon Nov 24, 2025
7d92a22
fix: only support jammy
yanksyoon Nov 24, 2025
3ab72db
chore: remove obsolete config.yaml file
yanksyoon Nov 24, 2025
e43c2a5
test: fix series to jammy
yanksyoon Nov 24, 2025
3048eab
revert charmcraft yaml related changes (incompatible old ops lib)
yanksyoon Nov 24, 2025
4d9e69a
revert charmcraft yaml contents (add back actions.yaml)
yanksyoon Nov 24, 2025
9f3fb07
remove unused subprocess
yanksyoon Nov 24, 2025
13fd5d9
charm file path
yanksyoon Nov 24, 2025
fc8fcea
revert debug
yanksyoon Nov 24, 2025
0b5aac7
test: use testing image for deployment
yanksyoon Nov 25, 2025
6907b4e
test: refactor: simplify image builder fixture logic and cleanup
yanksyoon Nov 25, 2025
642f6d7
test: update image builder fixture to use provide-github-runner-image…
yanksyoon Nov 26, 2025
4b48699
test: fix image builder w/ any-charm & pin revision to beta
yanksyoon Nov 26, 2025
df8ae40
test: revert e2e pre-built image use
yanksyoon Nov 26, 2025
f8a2b0b
test: infer image relation via interface
yanksyoon Nov 26, 2025
d9c268e
test: document fork behavior
yanksyoon Nov 26, 2025
a2fdc37
test: deploy all apps on virtual machine due to snapd bug
yanksyoon Nov 26, 2025
b22485b
test: supply explicit args to e2e tests
yanksyoon Nov 26, 2025
f654366
test: apply more root disk to default runner config
yanksyoon Nov 26, 2025
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
21 changes: 20 additions & 1 deletion .github/workflows/e2e_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,26 @@ jobs:
provider: lxd
test-tox-env: integration-juju3.6
modules: '["test_e2e"]'
extra-arguments: "-m openstack"
# INTEGRATION_TOKEN, OS_PASSWORD are passed through INTEGRATION_TEST_SECRET_ENV_VALUE_<N>
# mapping. See CONTRIBUTING.md for more details.
extra-arguments: |
-m=openstack \
--log-format="%(asctime)s %(levelname)s %(message)s" \
--path="${{ vars.INTEGRATION_TEST_PATH }}" \
--openstack-auth-url="${{ vars.INTEGRATION_TEST_OPENSTACK_AUTH_URL }}" \
--openstack-project-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_DOMAIN_NAME }}" \
--openstack-project-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_NAME }}" \
--openstack-user-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_USER_DOMAIN_NAME }}" \
--openstack-username="${{ vars.INTEGRATION_TEST_OPENSTACK_USERNAME }}" \
--openstack-region-name="${{ vars.INTEGRATION_TEST_OPENSTACK_REGION_NAME }}" \
--openstack-network-name="${{ vars.INTEGRATION_TEST_OPENSTACK_NETWORK_NAME }}" \
--openstack-flavor-name="${{ vars.INTEGRATION_TEST_OPENSTACK_FLAVOR_NAME }}" \
--https-proxy="${{ vars.INTEGRATION_TEST_HTTPS_PROXY }}" \
--http-proxy="${{ vars.INTEGRATION_TEST_HTTP_PROXY }}" \
--no-proxy="${{ vars.INTEGRATION_TEST_NO_PROXY }}" \
--openstack-https-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTPS_PROXY }}" \
--openstack-http-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTP_PROXY }}" \
--openstack-no-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_NO_PROXY }}"
self-hosted-runner: true
self-hosted-runner-label: pfe-ci

Expand Down
46 changes: 43 additions & 3 deletions .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,29 @@ jobs:
provider: lxd
test-tox-env: integration-juju3.6
modules: '["test_charm_metrics_failure", "test_charm_metrics_success", "test_charm_fork_repo", "test_charm_fork_path_change", "test_charm_no_runner", "test_charm_runner", "test_debug_ssh", "test_charm_upgrade", "test_reactive"]'
extra-arguments: '-m openstack --log-format="%(asctime)s %(levelname)s %(message)s"'
# INTEGRATION_TOKEN, OS_PASSWORD are passed through INTEGRATION_TEST_SECRET_ENV_VALUE_<N>
# mapping. See CONTRIBUTING.md for more details.
extra-arguments: |
-m=openstack \
--log-format="%(asctime)s %(levelname)s %(message)s" \
--path="${{ vars.INTEGRATION_TEST_PATH }}" \
--openstack-auth-url="${{ vars.INTEGRATION_TEST_OPENSTACK_AUTH_URL }}" \
--openstack-project-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_DOMAIN_NAME }}" \
--openstack-project-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_NAME }}" \
--openstack-user-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_USER_DOMAIN_NAME }}" \
--openstack-username="${{ vars.INTEGRATION_TEST_OPENSTACK_USERNAME }}" \
--openstack-region-name="${{ vars.INTEGRATION_TEST_OPENSTACK_REGION_NAME }}" \
--openstack-network-name="${{ vars.INTEGRATION_TEST_OPENSTACK_NETWORK_NAME }}" \
--openstack-flavor-name="${{ vars.INTEGRATION_TEST_OPENSTACK_FLAVOR_NAME }}" \
--https-proxy="${{ vars.INTEGRATION_TEST_HTTPS_PROXY }}" \
--http-proxy="${{ vars.INTEGRATION_TEST_HTTP_PROXY }}" \
--no-proxy="${{ vars.INTEGRATION_TEST_NO_PROXY }}" \
--openstack-https-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTPS_PROXY }}" \
--openstack-http-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTP_PROXY }}" \
--openstack-no-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_NO_PROXY }}" \
--test-image-id="${{ vars.INTEGRATION_TEST_IMAGE_ID }}"
self-hosted-runner: true
self-hosted-runner-label: pfe-ci
self-hosted-runner-label: pfe-ci
openstack-integration-tests-cross-controller-private-endpoint:
name: Cross controller integration test using private-endpoint
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@main
Expand All @@ -34,7 +54,27 @@ jobs:
provider: lxd
test-tox-env: integration-juju3.6
modules: '["test_prometheus_metrics"]'
extra-arguments: '-m openstack --log-format="%(asctime)s %(levelname)s %(message)s"'
# INTEGRATION_TOKEN, OS_PASSWORD are passed through INTEGRATION_TEST_SECRET_ENV_VALUE_<N>
# mapping. See CONTRIBUTING.md for more details.
extra-arguments: |
-m=openstack \
--log-format="%(asctime)s %(levelname)s %(message)s" \
--path="${{ vars.INTEGRATION_TEST_PATH }}" \
--openstack-auth-url="${{ vars.INTEGRATION_TEST_OPENSTACK_AUTH_URL }}" \
--openstack-project-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_DOMAIN_NAME }}" \
--openstack-project-name="${{ vars.INTEGRATION_TEST_OPENSTACK_PROJECT_NAME }}" \
--openstack-user-domain-name="${{ vars.INTEGRATION_TEST_OPENSTACK_USER_DOMAIN_NAME }}" \
--openstack-username="${{ vars.INTEGRATION_TEST_OPENSTACK_USERNAME }}" \
--openstack-region-name="${{ vars.INTEGRATION_TEST_OPENSTACK_REGION_NAME }}" \
--openstack-network-name="${{ vars.INTEGRATION_TEST_OPENSTACK_NETWORK_NAME }}" \
--openstack-flavor-name="${{ vars.INTEGRATION_TEST_OPENSTACK_FLAVOR_NAME }}" \
--https-proxy="${{ vars.INTEGRATION_TEST_HTTPS_PROXY }}" \
--http-proxy="${{ vars.INTEGRATION_TEST_HTTP_PROXY }}" \
--no-proxy="${{ vars.INTEGRATION_TEST_NO_PROXY }}" \
--openstack-https-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTPS_PROXY }}" \
--openstack-http-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_HTTP_PROXY }}" \
--openstack-no-proxy="${{ vars.INTEGRATION_TEST_OPENSTACK_NO_PROXY }}" \
--test-image-id="${{ vars.INTEGRATION_TEST_IMAGE_ID }}"
self-hosted-runner: true
self-hosted-runner-label: pfe-ci
allure-report:
Expand Down
13 changes: 13 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ that can be used for linting and formatting code when you're preparing contribut

> NOTE: Integration tests are currently intended to run on the CI and may not work locally without further argument.

<!-- vale Canonical.007-Headings-sentence-case = NO -->
#### CI testing setup guidelines
<!-- vale Canonical.007-Headings-sentence-case = YES -->

To prefer explicit setting arguments passing, use `extra-arguments` of the
[following reusable workflow](https://github.com/canonical/operator-workflows/blob/main/.github/workflows/integration_test_run.yaml)
to pass in non-sensitive values.
For sensitive values (`INTEGRATION_TOKEN`: `--token`, `OS_PASSWORD`: `--openstack-password`), map
them via `INTEGRATION_TEST_SECRET_ENV_NAME_<N>`
environment variable settings under [repository](https://github.com/canonical/github-runner-operator)
> settings > variables > actions.
This is to prevent GitHub from leaking secrets when passing them over the CLI calls (unresolved).

### Building the charm

Build the charm in this git repository using:
Expand Down
4 changes: 2 additions & 2 deletions actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
# See LICENSE file for licensing details.

check-runners:
description: Get info on active and registered runners
description: Get info on active and registered runners
flush-runners:
description: Clear out all runners and start a new set
description: Clear out all runners and start a new set
26 changes: 14 additions & 12 deletions charmcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@
# See LICENSE file for licensing details.

type: charm

parts:
charm:
charm-python-packages:
- setuptools>=75.8.0 # for jinja2
- setuptools>=75.8.0 # for jinja2
build-packages:
- git # for installing git source of pylxd
- libffi-dev # for cffi
- libssl-dev # for cryptography
- git # for installing git source of pylxd
- libffi-dev # for cffi
- libssl-dev # for cryptography
- pkg-config # for cryptography
build-snaps:
- rustup # for cryptography
override-build: |
rustup default stable
craftctl default

bases:
- build-on:
- name: "ubuntu"
channel: "22.04"
architectures:
- amd64
- name: "ubuntu"
channel: "22.04"
architectures:
- amd64
run-on:
- name: "ubuntu"
channel: "22.04"
architectures:
- amd64
- name: "ubuntu"
channel: "22.04"
architectures:
- amd64
1 change: 0 additions & 1 deletion metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ summary: Creates a group of self-hosted github runners.
description: |
A [Juju](https://juju.is/) [charm](https://juju.is/docs/olm/charmed-operators) managing
[self-hosted runners for GitHub Actions](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners).

Each unit of this charm will start a configurable number of virtual machines to host
self-hosted runners. Each runner performs only one job, after which it unregisters from GitHub to
ensure that each job runs in a clean environment. The charm will periodically check the number of
Expand Down
89 changes: 25 additions & 64 deletions tests/conftest.py
Comment thread
yanksyoon marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

"""Fixtures for github runner charm."""

import os

from pytest import Parser

Expand All @@ -25,13 +26,11 @@ def pytest_addoption(parser: Parser):
"An optionally comma separated GitHub Personal Access Token(s). "
"Add more than one to help reduce rate limiting."
),
default=os.environ.get("INTEGRATION_TOKEN"),
)
parser.addoption(
"--charm-file", action="store", help="The prebuilt github-runner-operator charm file."
)
parser.addoption(
"--token-alt", action="store", help="An alternative token to test the change of a token."
)
parser.addoption(
"--http-proxy",
action="store",
Expand All @@ -47,12 +46,6 @@ def pytest_addoption(parser: Parser):
action="store",
help="No proxy configuration value for juju model proxy configuration.",
)
parser.addoption(
"--openstack-clouds-yaml",
action="store",
help="The OpenStack clouds yaml file for the charm to use.",
default="",
)
parser.addoption(
"--use-existing-app-suffix",
action="store",
Expand Down Expand Up @@ -83,95 +76,56 @@ def pytest_addoption(parser: Parser):
)
# Private endpoint options AMD64
parser.addoption(
"--openstack-network-name-amd64",
"--openstack-network-name",
action="store",
help="The Openstack network to create testing instances under.",
)
parser.addoption(
"--openstack-flavor-name-amd64",
"--openstack-flavor-name",
action="store",
help="The Openstack flavor to create testing instances with.",
)
parser.addoption(
"--openstack-auth-url-amd64",
"--openstack-auth-url",
action="store",
help="The URL to Openstack authentication service, i.e. keystone.",
default=os.environ.get("OS_AUTH_URL"),
)
parser.addoption(
"--openstack-password-amd64",
"--openstack-password",
action="store",
help="The password to authenticate to Openstack service.",
default=os.environ.get("OS_PASSWORD"),
)
parser.addoption(
"--openstack-project-domain-name-amd64",
"--openstack-project-domain-name",
action="store",
help="The Openstack project domain name to use.",
default=os.environ.get("OS_PROJECT_DOMAIN_NAME"),
)
parser.addoption(
"--openstack-project-name-amd64",
"--openstack-project-name",
action="store",
help="The Openstack project name to use.",
default=os.environ.get("OS_PROJECT_NAME"),
)
parser.addoption(
"--openstack-user-domain-name-amd64",
"--openstack-user-domain-name",
action="store",
help="The Openstack user domain name to use.",
default=os.environ.get("OS_USER_DOMAIN_NAME"),
)
parser.addoption(
"--openstack-username-amd64",
"--openstack-username",
action="store",
help="The Openstack user to authenticate as.",
default=os.environ.get("OS_USERNAME"),
)
parser.addoption(
"--openstack-region-name-amd64",
action="store",
help="The Openstack region to authenticate to.",
)
# Private endpoint options ARM64
parser.addoption(
"--openstack-network-name-arm64",
action="store",
help="The Openstack network to create testing instances under.",
)
parser.addoption(
"--openstack-flavor-name-arm64",
action="store",
help="The Openstack flavor to create testing instances with.",
)
parser.addoption(
"--openstack-auth-url-arm64",
action="store",
help="The URL to Openstack authentication service, i.e. keystone.",
)
parser.addoption(
"--openstack-password-arm64",
action="store",
help="The password to authenticate to Openstack service.",
)
parser.addoption(
"--openstack-project-domain-name-arm64",
action="store",
help="The Openstack project domain name to use.",
)
parser.addoption(
"--openstack-project-name-arm64",
action="store",
help="The Openstack project name to use.",
)
parser.addoption(
"--openstack-user-domain-name-arm64",
action="store",
help="The Openstack user domain name to use.",
)
parser.addoption(
"--openstack-username-arm64",
action="store",
help="The Openstack user to authenticate as.",
)
parser.addoption(
"--openstack-region-name-arm64",
"--openstack-region-name",
action="store",
help="The Openstack region to authenticate to.",
default=os.environ.get("OS_REGION_NAME"),
)
# Interface testing args
parser.addoption(
Expand All @@ -186,3 +140,10 @@ def pytest_addoption(parser: Parser):
help="The flavor for testing openstack interfaces. The resource should be enough to boot the test image.",
default=None,
)
parser.addoption(
"--test-image-id",
action="store",
help="The image ID to use for testing. If provided, any-charm will be used to mock the "
"image builder for faster testing deployment.",
default=None,
)
Loading
Loading