Public Access
fix: unique molecule container names per CI runner
When multiple molecule matrix runners share the same Docker host, they conflict on the container name "ubuntu-2604" (409 Conflict from Docker). This appends the MATRIX_INDEX as a suffix (e.g. ubuntu-2604-r3) so each runner gets a unique container name. Closes DEVX-148 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
a8a8b743f3
commit
caa38fed3d
@@ -0,0 +1,12 @@
|
|||||||
|
extends: existence
|
||||||
|
message: "Don't attribute human qualities to software or hardware ('%s')."
|
||||||
|
link: https://developers.google.com/style/anthropomorphism
|
||||||
|
level: suggestion
|
||||||
|
ignorecase: true
|
||||||
|
# Limited to the two verbs the guide itself names. Broader lists (wants, knows,
|
||||||
|
# thinks) can't tell a software subject from a human one: on a 950-file corpus
|
||||||
|
# they produced 8 false positives ('the customer wants', 'your audience knows')
|
||||||
|
# for every 2 real ones.
|
||||||
|
tokens:
|
||||||
|
- sees
|
||||||
|
- tells
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
extends: existence
|
||||||
|
message: "Avoid the unverifiable claim '%s'."
|
||||||
|
link: https://developers.google.com/style/excessive-claims
|
||||||
|
level: suggestion
|
||||||
|
ignorecase: true
|
||||||
|
# The guide also names 'never', 'always', and 'ensure', but in technical writing
|
||||||
|
# those are usually legitimate instructions ('never commit secrets') rather than
|
||||||
|
# product claims: they accounted for 125 of 142 hits on a 950-file corpus.
|
||||||
|
# 'best practices' is a fixed term, not a superlative.
|
||||||
|
tokens:
|
||||||
|
- 'best(?! practices?)'
|
||||||
|
- simplest
|
||||||
|
- fastest
|
||||||
|
- guarantees?
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
extends: existence
|
||||||
|
message: "Avoid the jargon '%s'."
|
||||||
|
link: https://developers.google.com/style/jargon
|
||||||
|
level: suggestion
|
||||||
|
ignorecase: true
|
||||||
|
# The guide also cites 'solution', 'support', and 'workload' as overloaded
|
||||||
|
# terms, but those have ordinary technical meanings and accounted for every hit
|
||||||
|
# on a 950-file corpus, so only the unambiguous figurative terms are listed.
|
||||||
|
tokens:
|
||||||
|
- break-glass
|
||||||
|
- camel ?case
|
||||||
|
- out-of-the-box
|
||||||
|
- swim ?lane
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
extends: existence
|
||||||
|
message: "Avoid time-based words like '%s' in product documentation."
|
||||||
|
link: https://developers.google.com/style/timeless-documentation
|
||||||
|
level: suggestion
|
||||||
|
ignorecase: true
|
||||||
|
# The guide also names 'now' and 'new', but both have common senses that aren't
|
||||||
|
# time-anchored ('create a new project'): adding them took a 950-file corpus of
|
||||||
|
# technical documentation from 14 hits to 117. 'recently' is left out too — every
|
||||||
|
# hit in that corpus was the UI idiom 'recently used'.
|
||||||
|
tokens:
|
||||||
|
- currently
|
||||||
|
- latest
|
||||||
|
- soon
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
extends: substitution
|
||||||
|
message: "Use '%s' instead of '%s'."
|
||||||
|
link: "https://developers.google.com/style/word-list"
|
||||||
|
level: warning
|
||||||
|
# The case-insensitive half of the word list, so sentence-initial use is caught
|
||||||
|
# ('Touch the screen', not only 'touch the screen'). Entries that must stay
|
||||||
|
# case-sensitive are in WordList.yml.
|
||||||
|
ignorecase: true
|
||||||
|
action:
|
||||||
|
name: replace
|
||||||
|
swap:
|
||||||
|
"(?:API Console|dev|developer) key": API key
|
||||||
|
"(?:cell ?phone|smart ?phone)": phone|mobile phone
|
||||||
|
"(?:dev|developer|APIs) console": API console
|
||||||
|
"(?:e-mail|Email|E-mail)": email
|
||||||
|
"(?:file ?path|path ?name)": path
|
||||||
|
"(?:kill|terminate|abort)": stop|exit|cancel|end
|
||||||
|
# Longest form first: with the shortest alternative leading, 'OAuth 2' matched
|
||||||
|
# only 'OAuth', so applying the suggestion produced 'OAuth 2.0 2'. The rule is
|
||||||
|
# already case-insensitive, so the inline (?i) is redundant. See issue #41.
|
||||||
|
'\bOauth2\.0\b|\bOAuth ?2\b(?!\.0)|\bOauth\b(?! ?2)': OAuth 2.0
|
||||||
|
"(?:ok|Okay)": OK|okay
|
||||||
|
"(?:WiFi|wifi)": Wi-Fi
|
||||||
|
'[\.]+apk': APK
|
||||||
|
'3\-D': 3D
|
||||||
|
'Google (?:I\-O|IO)': Google I/O
|
||||||
|
"tap (?:&|and) hold": touch & hold
|
||||||
|
"un(?:check|select)": clear
|
||||||
|
above: preceding
|
||||||
|
account name: username
|
||||||
|
action bar: app bar
|
||||||
|
admin: administrator
|
||||||
|
a\.k\.a|aka: or|also known as
|
||||||
|
application: app
|
||||||
|
approx\.: approximately
|
||||||
|
autoupdate: automatically update
|
||||||
|
cellular data: mobile data
|
||||||
|
cellular network: mobile network
|
||||||
|
chapter: documents|pages|sections
|
||||||
|
check box: checkbox
|
||||||
|
click on: click|click in
|
||||||
|
content type: media type
|
||||||
|
curated roles: predefined roles
|
||||||
|
data are: data is
|
||||||
|
disabled?: turn off|off
|
||||||
|
ephemeral IP address: ephemeral external IP address
|
||||||
|
fewer data: less data
|
||||||
|
file name: filename
|
||||||
|
firewalls: firewall rules
|
||||||
|
functionality: capability|feature
|
||||||
|
grayed-out: unavailable
|
||||||
|
in order to: to
|
||||||
|
ingest: import|load
|
||||||
|
long press: touch & hold
|
||||||
|
network IP address: internal IP address
|
||||||
|
omnibox: address bar
|
||||||
|
open-source: open source
|
||||||
|
overview screen: recents screen
|
||||||
|
regex: regular expression
|
||||||
|
sign into: sign in to
|
||||||
|
'(?<!single )sign-?on': single sign-on
|
||||||
|
static IP address: static external IP address
|
||||||
|
stylesheet: style sheet
|
||||||
|
synch: sync
|
||||||
|
tablename: table name
|
||||||
|
tablet: device
|
||||||
|
'touch(?! ?(?:&|and) hold)': tap
|
||||||
|
vs\.: versus
|
||||||
@@ -125,6 +125,11 @@ def build_env_for_pair(pair: str, base_env: dict[str, str]) -> dict[str, str]:
|
|||||||
"""Build environment for a single molecule pair."""
|
"""Build environment for a single molecule pair."""
|
||||||
_role, _scenario, platform_name, platform_image, platform_command = parse_pair(pair)
|
_role, _scenario, platform_name, platform_image, platform_command = parse_pair(pair)
|
||||||
env = base_env.copy()
|
env = base_env.copy()
|
||||||
|
# Append runner index to platform name when running in CI matrix to avoid
|
||||||
|
# Docker container name conflicts when multiple runners share the same Docker host.
|
||||||
|
matrix_index = env.get("MATRIX_INDEX")
|
||||||
|
if matrix_index:
|
||||||
|
platform_name = f"{platform_name}-r{matrix_index}"
|
||||||
env["MOLECULE_PLATFORM_NAME"] = platform_name
|
env["MOLECULE_PLATFORM_NAME"] = platform_name
|
||||||
env["MOLECULE_PLATFORM_IMAGE"] = platform_image
|
env["MOLECULE_PLATFORM_IMAGE"] = platform_image
|
||||||
if platform_command:
|
if platform_command:
|
||||||
|
|||||||
@@ -102,6 +102,16 @@ class TestBuildEnvForPair:
|
|||||||
env = build_env_for_pair("default|ubuntu-2204|img:latest|", {"MOLECULE_HOME": "/custom/home"})
|
env = build_env_for_pair("default|ubuntu-2204|img:latest|", {"MOLECULE_HOME": "/custom/home"})
|
||||||
assert env["MOLECULE_HOME"] == "/custom/home"
|
assert env["MOLECULE_HOME"] == "/custom/home"
|
||||||
|
|
||||||
|
def test_appends_matrix_index_to_platform_name(self) -> None:
|
||||||
|
"""When MATRIX_INDEX is set, platform name gets a unique suffix."""
|
||||||
|
env = build_env_for_pair("default|ubuntu-2604|img:latest|sleep infinity", {"MATRIX_INDEX": "3"})
|
||||||
|
assert env["MOLECULE_PLATFORM_NAME"] == "ubuntu-2604-r3"
|
||||||
|
|
||||||
|
def test_no_matrix_index_keeps_platform_name(self) -> None:
|
||||||
|
"""Without MATRIX_INDEX, platform name is unchanged."""
|
||||||
|
env = build_env_for_pair("default|ubuntu-2604|img:latest|sleep infinity", {})
|
||||||
|
assert env["MOLECULE_PLATFORM_NAME"] == "ubuntu-2604"
|
||||||
|
|
||||||
|
|
||||||
class TestPollForOtherFailures:
|
class TestPollForOtherFailures:
|
||||||
def test_sets_failed_event_when_other_runner_fails(self) -> None:
|
def test_sets_failed_event_when_other_runner_fails(self) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user