all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fee5:6a3
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: fd70d562-44c2-4169-9fef-8320540a3a1f
        host_id: 4ba4344415ca7057d9956ea5de826bbc0b830981e82c0e0f191fa07b
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fee5:6a3
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.7.247
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.193.215
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fee5:6a3
        region: null
        slot: null
  vars:
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job mypy explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-jobs/.zuul.yaml@main#42>'
      - '<Job mypy explicit: None implied: None source: osism/python-osism/.zuul.yaml@main#143>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: 6232fdfb1eed49d1a41816ca19908726
      build_refs:
      - branch: main
        change: '2460'
        change_message: "Add unit tests for osism/services websocket_manager and event_bridge\n\nCloses
          #2357.\n\nCreates the `tests/unit/services/` package with unit tests for
          `osism/services/websocket_manager.py` and `osism/services/event_bridge.py`,
          which previously had no coverage.\n\n## test_websocket_manager.py\n\n- `EventMessage`:
          constructor attributes, UUID4 id uniqueness, ISO 8601 `Z`-suffixed timestamp,
          exact `to_dict()` keys, `to_json()` round trip\n- `WebSocketConnection.matches_filters()`:
          no-filter pass-through, event/node/service filters incl. `node_name=None`
          rejection, `\"\"` \u2192 `unknown` service mapping and AND-combination of
          filters\n- `WebSocketManager.connect()`/`disconnect()`: accept + registration,
          broadcaster started only once while running (`done()` check), restart after
          completion, no-op disconnect for unknown websockets\n- `update_filters()`:
          full and partial updates, clearing via `[]`, unknown websocket no-op\n-
          `add_event()`/`send_heartbeat()`: queueing, early return without connections,
          heartbeat event shape\n- `broadcast_event_from_notification()`: identifier
          extraction for baremetal/compute/nova/network/neutron/volume/image/identity
          payloads incl. fallback keys, missing payload keys, unknown service types,
          empty event type, payload copy semantics and the swallowed-exception path\n-
          `_broadcast_events()`: filtered delivery, `WebSocketDisconnect` and generic-error
          connection cleanup, consumption without connections and clean cancellation\n\n##
          test_event_bridge.py\n\n- `_init_redis()`: default connection parameters,
          `REDIS_HOST`/`REDIS_PORT`/`REDIS_DB` overrides, ping failure handling and
          the `REDIS_AVAILABLE = False` local-queue-only path\n- `set_websocket_manager()`:
          thread startup guards for subscriber and processor threads\n- `add_event()`:
          publish payload, zero-subscriber warning, reconnect-then-publish, fallback
          to the local queue when reconnection fails, `queue.Full` and generic error
          swallowing\n- `_redis_subscriber_loop()`: missing subscriber, subscribe/get_message
          flow, message dispatch with and without a WebSocket manager, invalid JSON,
          processing errors, resubscribe after `get_message` failures, back-off with
          `_init_redis()` re-invocation when `subscribe()` raises, retry exhaustion
          and swallowed `close()` errors\n- `_process_single_event()`: missing-manager
          warning, `AsyncMock` broadcast dispatch and swallowed coroutine errors\n-
          `_process_events()`: queued event processing with `task_done()`, empty-queue
          continuation, pre-set shutdown exit and error continuation\n- `shutdown()`:
          shutdown event, subscriber close incl. error path and conditional thread
          joins\n\n## Notes\n\n- All tests use fresh `WebSocketManager`/`EventBridge`
          instances instead of the module-level singletons; `EventBridge` is always
          constructed with `redis.Redis` patched.\n- The thread loops are called synchronously
          and terminated via `_shutdown_event`-driven side effects; the asyncio broadcaster
          tests bound the task with cancellation in `finally` and carry `pytest-timeout`
          markers, so no test can hang CI.\n- `pytest-asyncio` 1.4.0 is added to the
          Pipfile `[dev-packages]` (compatible with pytest 9, `pytest<10,>=8.4`);
          async tests are marked explicitly with `@pytest.mark.asyncio`, so `--strict-markers`
          stays happy. `Pipfile.lock` was regenerated on linux/amd64 with Python 3.12
          to match CI.\n- One deviation from the issue text: a failing `get_message()`
          only breaks the inner loop and triggers a resubscribe; the retry counter
          and `_shutdown_event.wait()` back-off only engage when `subscribe()` itself
          raises. The tests pin the actual behavior for both paths.\n\n\U0001F916
          Generated with [Claude Code](https://claude.com/claude-code)"
        change_url: https://github.com/osism/python-osism/pull/2460
        commit_id: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        patchset: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      buildset: dc90cd2d5de84b9fae0b931266ec042d
      buildset_refs:
      - branch: main
        change: '2460'
        change_message: "Add unit tests for osism/services websocket_manager and event_bridge\n\nCloses
          #2357.\n\nCreates the `tests/unit/services/` package with unit tests for
          `osism/services/websocket_manager.py` and `osism/services/event_bridge.py`,
          which previously had no coverage.\n\n## test_websocket_manager.py\n\n- `EventMessage`:
          constructor attributes, UUID4 id uniqueness, ISO 8601 `Z`-suffixed timestamp,
          exact `to_dict()` keys, `to_json()` round trip\n- `WebSocketConnection.matches_filters()`:
          no-filter pass-through, event/node/service filters incl. `node_name=None`
          rejection, `\"\"` \u2192 `unknown` service mapping and AND-combination of
          filters\n- `WebSocketManager.connect()`/`disconnect()`: accept + registration,
          broadcaster started only once while running (`done()` check), restart after
          completion, no-op disconnect for unknown websockets\n- `update_filters()`:
          full and partial updates, clearing via `[]`, unknown websocket no-op\n-
          `add_event()`/`send_heartbeat()`: queueing, early return without connections,
          heartbeat event shape\n- `broadcast_event_from_notification()`: identifier
          extraction for baremetal/compute/nova/network/neutron/volume/image/identity
          payloads incl. fallback keys, missing payload keys, unknown service types,
          empty event type, payload copy semantics and the swallowed-exception path\n-
          `_broadcast_events()`: filtered delivery, `WebSocketDisconnect` and generic-error
          connection cleanup, consumption without connections and clean cancellation\n\n##
          test_event_bridge.py\n\n- `_init_redis()`: default connection parameters,
          `REDIS_HOST`/`REDIS_PORT`/`REDIS_DB` overrides, ping failure handling and
          the `REDIS_AVAILABLE = False` local-queue-only path\n- `set_websocket_manager()`:
          thread startup guards for subscriber and processor threads\n- `add_event()`:
          publish payload, zero-subscriber warning, reconnect-then-publish, fallback
          to the local queue when reconnection fails, `queue.Full` and generic error
          swallowing\n- `_redis_subscriber_loop()`: missing subscriber, subscribe/get_message
          flow, message dispatch with and without a WebSocket manager, invalid JSON,
          processing errors, resubscribe after `get_message` failures, back-off with
          `_init_redis()` re-invocation when `subscribe()` raises, retry exhaustion
          and swallowed `close()` errors\n- `_process_single_event()`: missing-manager
          warning, `AsyncMock` broadcast dispatch and swallowed coroutine errors\n-
          `_process_events()`: queued event processing with `task_done()`, empty-queue
          continuation, pre-set shutdown exit and error continuation\n- `shutdown()`:
          shutdown event, subscriber close incl. error path and conditional thread
          joins\n\n## Notes\n\n- All tests use fresh `WebSocketManager`/`EventBridge`
          instances instead of the module-level singletons; `EventBridge` is always
          constructed with `redis.Redis` patched.\n- The thread loops are called synchronously
          and terminated via `_shutdown_event`-driven side effects; the asyncio broadcaster
          tests bound the task with cancellation in `finally` and carry `pytest-timeout`
          markers, so no test can hang CI.\n- `pytest-asyncio` 1.4.0 is added to the
          Pipfile `[dev-packages]` (compatible with pytest 9, `pytest<10,>=8.4`);
          async tests are marked explicitly with `@pytest.mark.asyncio`, so `--strict-markers`
          stays happy. `Pipfile.lock` was regenerated on linux/amd64 with Python 3.12
          to match CI.\n- One deviation from the issue text: a failing `get_message()`
          only breaks the inner loop and triggers a resubscribe; the retry counter
          and `_shutdown_event.wait()` back-off only engage when `subscribe()` itself
          raises. The tests pin the actual behavior for both paths.\n\n\U0001F916
          Generated with [Claude Code](https://claude.com/claude-code)"
        change_url: https://github.com/osism/python-osism/pull/2460
        commit_id: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        patchset: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      change: '2460'
      change_message: "Add unit tests for osism/services websocket_manager and event_bridge\n\nCloses
        #2357.\n\nCreates the `tests/unit/services/` package with unit tests for `osism/services/websocket_manager.py`
        and `osism/services/event_bridge.py`, which previously had no coverage.\n\n##
        test_websocket_manager.py\n\n- `EventMessage`: constructor attributes, UUID4
        id uniqueness, ISO 8601 `Z`-suffixed timestamp, exact `to_dict()` keys, `to_json()`
        round trip\n- `WebSocketConnection.matches_filters()`: no-filter pass-through,
        event/node/service filters incl. `node_name=None` rejection, `\"\"` \u2192
        `unknown` service mapping and AND-combination of filters\n- `WebSocketManager.connect()`/`disconnect()`:
        accept + registration, broadcaster started only once while running (`done()`
        check), restart after completion, no-op disconnect for unknown websockets\n-
        `update_filters()`: full and partial updates, clearing via `[]`, unknown websocket
        no-op\n- `add_event()`/`send_heartbeat()`: queueing, early return without
        connections, heartbeat event shape\n- `broadcast_event_from_notification()`:
        identifier extraction for baremetal/compute/nova/network/neutron/volume/image/identity
        payloads incl. fallback keys, missing payload keys, unknown service types,
        empty event type, payload copy semantics and the swallowed-exception path\n-
        `_broadcast_events()`: filtered delivery, `WebSocketDisconnect` and generic-error
        connection cleanup, consumption without connections and clean cancellation\n\n##
        test_event_bridge.py\n\n- `_init_redis()`: default connection parameters,
        `REDIS_HOST`/`REDIS_PORT`/`REDIS_DB` overrides, ping failure handling and
        the `REDIS_AVAILABLE = False` local-queue-only path\n- `set_websocket_manager()`:
        thread startup guards for subscriber and processor threads\n- `add_event()`:
        publish payload, zero-subscriber warning, reconnect-then-publish, fallback
        to the local queue when reconnection fails, `queue.Full` and generic error
        swallowing\n- `_redis_subscriber_loop()`: missing subscriber, subscribe/get_message
        flow, message dispatch with and without a WebSocket manager, invalid JSON,
        processing errors, resubscribe after `get_message` failures, back-off with
        `_init_redis()` re-invocation when `subscribe()` raises, retry exhaustion
        and swallowed `close()` errors\n- `_process_single_event()`: missing-manager
        warning, `AsyncMock` broadcast dispatch and swallowed coroutine errors\n-
        `_process_events()`: queued event processing with `task_done()`, empty-queue
        continuation, pre-set shutdown exit and error continuation\n- `shutdown()`:
        shutdown event, subscriber close incl. error path and conditional thread joins\n\n##
        Notes\n\n- All tests use fresh `WebSocketManager`/`EventBridge` instances
        instead of the module-level singletons; `EventBridge` is always constructed
        with `redis.Redis` patched.\n- The thread loops are called synchronously and
        terminated via `_shutdown_event`-driven side effects; the asyncio broadcaster
        tests bound the task with cancellation in `finally` and carry `pytest-timeout`
        markers, so no test can hang CI.\n- `pytest-asyncio` 1.4.0 is added to the
        Pipfile `[dev-packages]` (compatible with pytest 9, `pytest<10,>=8.4`); async
        tests are marked explicitly with `@pytest.mark.asyncio`, so `--strict-markers`
        stays happy. `Pipfile.lock` was regenerated on linux/amd64 with Python 3.12
        to match CI.\n- One deviation from the issue text: a failing `get_message()`
        only breaks the inner loop and triggers a resubscribe; the retry counter and
        `_shutdown_event.wait()` back-off only engage when `subscribe()` itself raises.
        The tests pin the actual behavior for both paths.\n\n\U0001F916 Generated
        with [Claude Code](https://claude.com/claude-code)"
      change_url: https://github.com/osism/python-osism/pull/2460
      child_jobs: []
      commit_id: 322dfc76ed13012c115713e37c60fc4fc7a6d487
      event_id: 51242060-7ef7-11f1-9049-4b99333a0f48
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/6232fdfb1eed49d1a41816ca19908726/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/6232fdfb1eed49d1a41816ca19908726/work/logs
        result_data_file: /var/lib/zuul/builds/6232fdfb1eed49d1a41816ca19908726/work/results.json
        src_root: /var/lib/zuul/builds/6232fdfb1eed49d1a41816ca19908726/work/src
        work_root: /var/lib/zuul/builds/6232fdfb1eed49d1a41816ca19908726/work
      include_vars: []
      items:
      - branch: main
        change: '2460'
        change_message: "Add unit tests for osism/services websocket_manager and event_bridge\n\nCloses
          #2357.\n\nCreates the `tests/unit/services/` package with unit tests for
          `osism/services/websocket_manager.py` and `osism/services/event_bridge.py`,
          which previously had no coverage.\n\n## test_websocket_manager.py\n\n- `EventMessage`:
          constructor attributes, UUID4 id uniqueness, ISO 8601 `Z`-suffixed timestamp,
          exact `to_dict()` keys, `to_json()` round trip\n- `WebSocketConnection.matches_filters()`:
          no-filter pass-through, event/node/service filters incl. `node_name=None`
          rejection, `\"\"` \u2192 `unknown` service mapping and AND-combination of
          filters\n- `WebSocketManager.connect()`/`disconnect()`: accept + registration,
          broadcaster started only once while running (`done()` check), restart after
          completion, no-op disconnect for unknown websockets\n- `update_filters()`:
          full and partial updates, clearing via `[]`, unknown websocket no-op\n-
          `add_event()`/`send_heartbeat()`: queueing, early return without connections,
          heartbeat event shape\n- `broadcast_event_from_notification()`: identifier
          extraction for baremetal/compute/nova/network/neutron/volume/image/identity
          payloads incl. fallback keys, missing payload keys, unknown service types,
          empty event type, payload copy semantics and the swallowed-exception path\n-
          `_broadcast_events()`: filtered delivery, `WebSocketDisconnect` and generic-error
          connection cleanup, consumption without connections and clean cancellation\n\n##
          test_event_bridge.py\n\n- `_init_redis()`: default connection parameters,
          `REDIS_HOST`/`REDIS_PORT`/`REDIS_DB` overrides, ping failure handling and
          the `REDIS_AVAILABLE = False` local-queue-only path\n- `set_websocket_manager()`:
          thread startup guards for subscriber and processor threads\n- `add_event()`:
          publish payload, zero-subscriber warning, reconnect-then-publish, fallback
          to the local queue when reconnection fails, `queue.Full` and generic error
          swallowing\n- `_redis_subscriber_loop()`: missing subscriber, subscribe/get_message
          flow, message dispatch with and without a WebSocket manager, invalid JSON,
          processing errors, resubscribe after `get_message` failures, back-off with
          `_init_redis()` re-invocation when `subscribe()` raises, retry exhaustion
          and swallowed `close()` errors\n- `_process_single_event()`: missing-manager
          warning, `AsyncMock` broadcast dispatch and swallowed coroutine errors\n-
          `_process_events()`: queued event processing with `task_done()`, empty-queue
          continuation, pre-set shutdown exit and error continuation\n- `shutdown()`:
          shutdown event, subscriber close incl. error path and conditional thread
          joins\n\n## Notes\n\n- All tests use fresh `WebSocketManager`/`EventBridge`
          instances instead of the module-level singletons; `EventBridge` is always
          constructed with `redis.Redis` patched.\n- The thread loops are called synchronously
          and terminated via `_shutdown_event`-driven side effects; the asyncio broadcaster
          tests bound the task with cancellation in `finally` and carry `pytest-timeout`
          markers, so no test can hang CI.\n- `pytest-asyncio` 1.4.0 is added to the
          Pipfile `[dev-packages]` (compatible with pytest 9, `pytest<10,>=8.4`);
          async tests are marked explicitly with `@pytest.mark.asyncio`, so `--strict-markers`
          stays happy. `Pipfile.lock` was regenerated on linux/amd64 with Python 3.12
          to match CI.\n- One deviation from the issue text: a failing `get_message()`
          only breaks the inner loop and triggers a resubscribe; the retry counter
          and `_shutdown_event.wait()` back-off only engage when `subscribe()` itself
          raises. The tests pin the actual behavior for both paths.\n\n\U0001F916
          Generated with [Claude Code](https://claude.com/claude-code)"
        change_url: https://github.com/osism/python-osism/pull/2460
        commit_id: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        patchset: 322dfc76ed13012c115713e37c60fc4fc7a6d487
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
        topic: null
      job: mypy
      jobtags: []
      max_attempts: 3
      message: QWRkIHVuaXQgdGVzdHMgZm9yIG9zaXNtL3NlcnZpY2VzIHdlYnNvY2tldF9tYW5hZ2VyIGFuZCBldmVudF9icmlkZ2UKCkNsb3NlcyAjMjM1Ny4KCkNyZWF0ZXMgdGhlIGB0ZXN0cy91bml0L3NlcnZpY2VzL2AgcGFja2FnZSB3aXRoIHVuaXQgdGVzdHMgZm9yIGBvc2lzbS9zZXJ2aWNlcy93ZWJzb2NrZXRfbWFuYWdlci5weWAgYW5kIGBvc2lzbS9zZXJ2aWNlcy9ldmVudF9icmlkZ2UucHlgLCB3aGljaCBwcmV2aW91c2x5IGhhZCBubyBjb3ZlcmFnZS4KCiMjIHRlc3Rfd2Vic29ja2V0X21hbmFnZXIucHkKCi0gYEV2ZW50TWVzc2FnZWA6IGNvbnN0cnVjdG9yIGF0dHJpYnV0ZXMsIFVVSUQ0IGlkIHVuaXF1ZW5lc3MsIElTTyA4NjAxIGBaYC1zdWZmaXhlZCB0aW1lc3RhbXAsIGV4YWN0IGB0b19kaWN0KClgIGtleXMsIGB0b19qc29uKClgIHJvdW5kIHRyaXAKLSBgV2ViU29ja2V0Q29ubmVjdGlvbi5tYXRjaGVzX2ZpbHRlcnMoKWA6IG5vLWZpbHRlciBwYXNzLXRocm91Z2gsIGV2ZW50L25vZGUvc2VydmljZSBmaWx0ZXJzIGluY2wuIGBub2RlX25hbWU9Tm9uZWAgcmVqZWN0aW9uLCBgIiJgIOKGkiBgdW5rbm93bmAgc2VydmljZSBtYXBwaW5nIGFuZCBBTkQtY29tYmluYXRpb24gb2YgZmlsdGVycwotIGBXZWJTb2NrZXRNYW5hZ2VyLmNvbm5lY3QoKWAvYGRpc2Nvbm5lY3QoKWA6IGFjY2VwdCArIHJlZ2lzdHJhdGlvbiwgYnJvYWRjYXN0ZXIgc3RhcnRlZCBvbmx5IG9uY2Ugd2hpbGUgcnVubmluZyAoYGRvbmUoKWAgY2hlY2spLCByZXN0YXJ0IGFmdGVyIGNvbXBsZXRpb24sIG5vLW9wIGRpc2Nvbm5lY3QgZm9yIHVua25vd24gd2Vic29ja2V0cwotIGB1cGRhdGVfZmlsdGVycygpYDogZnVsbCBhbmQgcGFydGlhbCB1cGRhdGVzLCBjbGVhcmluZyB2aWEgYFtdYCwgdW5rbm93biB3ZWJzb2NrZXQgbm8tb3AKLSBgYWRkX2V2ZW50KClgL2BzZW5kX2hlYXJ0YmVhdCgpYDogcXVldWVpbmcsIGVhcmx5IHJldHVybiB3aXRob3V0IGNvbm5lY3Rpb25zLCBoZWFydGJlYXQgZXZlbnQgc2hhcGUKLSBgYnJvYWRjYXN0X2V2ZW50X2Zyb21fbm90aWZpY2F0aW9uKClgOiBpZGVudGlmaWVyIGV4dHJhY3Rpb24gZm9yIGJhcmVtZXRhbC9jb21wdXRlL25vdmEvbmV0d29yay9uZXV0cm9uL3ZvbHVtZS9pbWFnZS9pZGVudGl0eSBwYXlsb2FkcyBpbmNsLiBmYWxsYmFjayBrZXlzLCBtaXNzaW5nIHBheWxvYWQga2V5cywgdW5rbm93biBzZXJ2aWNlIHR5cGVzLCBlbXB0eSBldmVudCB0eXBlLCBwYXlsb2FkIGNvcHkgc2VtYW50aWNzIGFuZCB0aGUgc3dhbGxvd2VkLWV4Y2VwdGlvbiBwYXRoCi0gYF9icm9hZGNhc3RfZXZlbnRzKClgOiBmaWx0ZXJlZCBkZWxpdmVyeSwgYFdlYlNvY2tldERpc2Nvbm5lY3RgIGFuZCBnZW5lcmljLWVycm9yIGNvbm5lY3Rpb24gY2xlYW51cCwgY29uc3VtcHRpb24gd2l0aG91dCBjb25uZWN0aW9ucyBhbmQgY2xlYW4gY2FuY2VsbGF0aW9uCgojIyB0ZXN0X2V2ZW50X2JyaWRnZS5weQoKLSBgX2luaXRfcmVkaXMoKWA6IGRlZmF1bHQgY29ubmVjdGlvbiBwYXJhbWV0ZXJzLCBgUkVESVNfSE9TVGAvYFJFRElTX1BPUlRgL2BSRURJU19EQmAgb3ZlcnJpZGVzLCBwaW5nIGZhaWx1cmUgaGFuZGxpbmcgYW5kIHRoZSBgUkVESVNfQVZBSUxBQkxFID0gRmFsc2VgIGxvY2FsLXF1ZXVlLW9ubHkgcGF0aAotIGBzZXRfd2Vic29ja2V0X21hbmFnZXIoKWA6IHRocmVhZCBzdGFydHVwIGd1YXJkcyBmb3Igc3Vic2NyaWJlciBhbmQgcHJvY2Vzc29yIHRocmVhZHMKLSBgYWRkX2V2ZW50KClgOiBwdWJsaXNoIHBheWxvYWQsIHplcm8tc3Vic2NyaWJlciB3YXJuaW5nLCByZWNvbm5lY3QtdGhlbi1wdWJsaXNoLCBmYWxsYmFjayB0byB0aGUgbG9jYWwgcXVldWUgd2hlbiByZWNvbm5lY3Rpb24gZmFpbHMsIGBxdWV1ZS5GdWxsYCBhbmQgZ2VuZXJpYyBlcnJvciBzd2FsbG93aW5nCi0gYF9yZWRpc19zdWJzY3JpYmVyX2xvb3AoKWA6IG1pc3Npbmcgc3Vic2NyaWJlciwgc3Vic2NyaWJlL2dldF9tZXNzYWdlIGZsb3csIG1lc3NhZ2UgZGlzcGF0Y2ggd2l0aCBhbmQgd2l0aG91dCBhIFdlYlNvY2tldCBtYW5hZ2VyLCBpbnZhbGlkIEpTT04sIHByb2Nlc3NpbmcgZXJyb3JzLCByZXN1YnNjcmliZSBhZnRlciBgZ2V0X21lc3NhZ2VgIGZhaWx1cmVzLCBiYWNrLW9mZiB3aXRoIGBfaW5pdF9yZWRpcygpYCByZS1pbnZvY2F0aW9uIHdoZW4gYHN1YnNjcmliZSgpYCByYWlzZXMsIHJldHJ5IGV4aGF1c3Rpb24gYW5kIHN3YWxsb3dlZCBgY2xvc2UoKWAgZXJyb3JzCi0gYF9wcm9jZXNzX3NpbmdsZV9ldmVudCgpYDogbWlzc2luZy1tYW5hZ2VyIHdhcm5pbmcsIGBBc3luY01vY2tgIGJyb2FkY2FzdCBkaXNwYXRjaCBhbmQgc3dhbGxvd2VkIGNvcm91dGluZSBlcnJvcnMKLSBgX3Byb2Nlc3NfZXZlbnRzKClgOiBxdWV1ZWQgZXZlbnQgcHJvY2Vzc2luZyB3aXRoIGB0YXNrX2RvbmUoKWAsIGVtcHR5LXF1ZXVlIGNvbnRpbnVhdGlvbiwgcHJlLXNldCBzaHV0ZG93biBleGl0IGFuZCBlcnJvciBjb250aW51YXRpb24KLSBgc2h1dGRvd24oKWA6IHNodXRkb3duIGV2ZW50LCBzdWJzY3JpYmVyIGNsb3NlIGluY2wuIGVycm9yIHBhdGggYW5kIGNvbmRpdGlvbmFsIHRocmVhZCBqb2lucwoKIyMgTm90ZXMKCi0gQWxsIHRlc3RzIHVzZSBmcmVzaCBgV2ViU29ja2V0TWFuYWdlcmAvYEV2ZW50QnJpZGdlYCBpbnN0YW5jZXMgaW5zdGVhZCBvZiB0aGUgbW9kdWxlLWxldmVsIHNpbmdsZXRvbnM7IGBFdmVudEJyaWRnZWAgaXMgYWx3YXlzIGNvbnN0cnVjdGVkIHdpdGggYHJlZGlzLlJlZGlzYCBwYXRjaGVkLgotIFRoZSB0aHJlYWQgbG9vcHMgYXJlIGNhbGxlZCBzeW5jaHJvbm91c2x5IGFuZCB0ZXJtaW5hdGVkIHZpYSBgX3NodXRkb3duX2V2ZW50YC1kcml2ZW4gc2lkZSBlZmZlY3RzOyB0aGUgYXN5bmNpbyBicm9hZGNhc3RlciB0ZXN0cyBib3VuZCB0aGUgdGFzayB3aXRoIGNhbmNlbGxhdGlvbiBpbiBgZmluYWxseWAgYW5kIGNhcnJ5IGBweXRlc3QtdGltZW91dGAgbWFya2Vycywgc28gbm8gdGVzdCBjYW4gaGFuZyBDSS4KLSBgcHl0ZXN0LWFzeW5jaW9gIDEuNC4wIGlzIGFkZGVkIHRvIHRoZSBQaXBmaWxlIGBbZGV2LXBhY2thZ2VzXWAgKGNvbXBhdGlibGUgd2l0aCBweXRlc3QgOSwgYHB5dGVzdDwxMCw+PTguNGApOyBhc3luYyB0ZXN0cyBhcmUgbWFya2VkIGV4cGxpY2l0bHkgd2l0aCBgQHB5dGVzdC5tYXJrLmFzeW5jaW9gLCBzbyBgLS1zdHJpY3QtbWFya2Vyc2Agc3RheXMgaGFwcHkuIGBQaXBmaWxlLmxvY2tgIHdhcyByZWdlbmVyYXRlZCBvbiBsaW51eC9hbWQ2NCB3aXRoIFB5dGhvbiAzLjEyIHRvIG1hdGNoIENJLgotIE9uZSBkZXZpYXRpb24gZnJvbSB0aGUgaXNzdWUgdGV4dDogYSBmYWlsaW5nIGBnZXRfbWVzc2FnZSgpYCBvbmx5IGJyZWFrcyB0aGUgaW5uZXIgbG9vcCBhbmQgdHJpZ2dlcnMgYSByZXN1YnNjcmliZTsgdGhlIHJldHJ5IGNvdW50ZXIgYW5kIGBfc2h1dGRvd25fZXZlbnQud2FpdCgpYCBiYWNrLW9mZiBvbmx5IGVuZ2FnZSB3aGVuIGBzdWJzY3JpYmUoKWAgaXRzZWxmIHJhaXNlcy4gVGhlIHRlc3RzIHBpbiB0aGUgYWN0dWFsIGJlaGF2aW9yIGZvciBib3RoIHBhdGhzLgoK8J+kliBHZW5lcmF0ZWQgd2l0aCBbQ2xhdWRlIENvZGVdKGh0dHBzOi8vY2xhdWRlLmNvbS9jbGF1ZGUtY29kZSk=
      patchset: 322dfc76ed13012c115713e37c60fc4fc7a6d487
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 1d71e58c93442038e695a5d883d57a603182c7ae
          untrusted/project_0/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 1d71e58c93442038e695a5d883d57a603182c7ae
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
        playbooks:
        - path: untrusted/project_0/github.com/osism/zuul-jobs/playbooks/mypy/run.yaml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_0/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_0/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_1/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_1/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: playbook branch
            link_name: ansible/playbook_0/role_2/zuul-jobs
            link_target: untrusted/project_0/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_2/zuul-jobs/roles
      post_review: false
      post_timeout: 1800
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/python-osism
        name: osism/python-osism
        short_name: python-osism
        src_dir: src/github.com/osism/python-osism
      projects:
        github.com/osism/python-osism:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          checkout: main
          checkout_description: zuul branch
          commit: 23178ef1c629e7caf71109345b2a613d5c50d461
          name: osism/python-osism
          required: false
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
      ref: refs/pull/2460/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
