Skip to content
Merged
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
2 changes: 1 addition & 1 deletion action-scripts/label-dispatcher/README-ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ bundle exec ruby label-dispatcher/bin/dispatcher help_usage

## 変更パスの照合

変更ファイルを定義された stack のパスに照合し、サービス・環境・任意 placeholder を抽出します。`environments` を持つ stack は定義環境だけを受け付け、パスに環境名がない場合は定義環境ごとに評価します。両方の属性マップがない stack は変更パスから抽出した環境名を使います。`attributes` を持つ stack は `environment: null` の照合として扱います。
変更ファイルを定義された stack のパスに照合し、サービス・環境・任意 placeholder を抽出します。stack のパスはディレクトリを指すため、そのディレクトリ配下にある変更ファイルだけが一致し、ファイル自身のパスが解決後のパスと等しい場合は対象外です。`environments` を持つ stack は定義環境だけを受け付け、パスに環境名がない場合は定義環境ごとに評価します。両方の属性マップがない stack は変更パスから抽出した環境名を使います。`attributes` を持つ stack は `environment: null` の照合として扱います。

各照合に除外条件を適用し、除外されない照合が一つでもあるサービスを一度だけラベル対象にします。サービス全体のディレクトリを検出対象にする場合は、そのパスも stack に定義します。削除されたファイルも照合するため、ディレクトリの存在は要求しません。

Expand Down
2 changes: 1 addition & 1 deletion action-scripts/label-dispatcher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ The dispatcher sets the following environment variables for GitHub Actions:

## Change Matching

Matches changed files against configured stack paths and extracts services, environments, and arbitrary placeholders. A stack with `environments` accepts only its declared names; a path without an environment name is evaluated for each declared environment. A stack with neither attribute map uses the environment captured from the changed path. A stack with `attributes` is evaluated with `environment: null`.
Matches changed files against configured stack paths and extracts services, environments, and arbitrary placeholders. A stack path resolves to a directory, so a changed file matches only when it is located under that directory; a file whose own path equals the resolved path is ignored. A stack with `environments` accepts only its declared names; a path without an environment name is evaluated for each declared environment. A stack with neither attribute map uses the environment captured from the changed path. A stack with `attributes` is evaluated with `environment: null`.

Applies exclusion conditions to each match. A service receives one label if at least one match is not excluded. To detect changes throughout a service directory, include that path in a stack definition. Directories need not exist because deleted files are also matched.

Expand Down
5 changes: 2 additions & 3 deletions action-scripts/shared/entities/pattern_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ def self.extract(pattern, path)
match_to_hash(regex.match(path), pattern)
end

# Like extract, but only requires the pattern to match the prefix of path.
# Path may carry additional "/"-separated segments after the pattern.
# Like extract, but path must carry at least one "/"-separated segment after the pattern.
def self.extract_prefix(pattern, path)
return nil if pattern.nil? || path.nil?
regex = Regexp.new("\\A#{compile_regex_body(pattern)}(?:/.*)?\\z")
regex = Regexp.new("\\A#{compile_regex_body(pattern)}/.+\\z")
match_to_hash(regex.match(path), pattern)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ def services
expect(services).to eq(['api'])
end

it 'ignores files placed at the service position' do
config_hash['stacks'] = [{ 'name' => 'container', 'paths' => ['dystopia/{service}'], 'attributes' => {} }]
changed_files.replace(['dystopia/README.md', 'dystopia/api/main.rb'])
expect(services).to eq(['api'])
end

it 'ignores files placed at the environment position' do
config_hash['stacks'] = [{ 'name' => 'kubernetes', 'paths' => ['dystopia/{service}/kubernetes/overlays/{environment}'] }]
changed_files.replace(['dystopia/web/kubernetes/overlays/README.md', 'dystopia/api/kubernetes/overlays/develop/kustomization.yaml'])
expect(services).to eq(['api'])
end

it 'uses AND within conditions and OR across conditions' do
stack['exclude'] = [{ 'team' => 'platform', 'service' => 'demo' }, { 'team' => 'sandbox' }]
changed_files.replace(['teams/platform/api/aws/develop/main.tf', 'teams/sandbox/api/aws/develop/main.tf', 'teams/platform/demo/aws/develop/main.tf'])
Expand Down
10 changes: 8 additions & 2 deletions action-scripts/spec/shared/entities/pattern_matcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,16 @@
expect(result).to eq('service' => 'foo')
end

it 'matches when path equals the pattern exactly' do
it 'returns nil when the path equals the pattern exactly' do
expect(
described_class.extract_prefix('{service}/terragrunt', 'foo/terragrunt')
).to eq('service' => 'foo')
).to be_nil
end

it 'returns nil when the path ends with a separator after the pattern' do
expect(
described_class.extract_prefix('{service}/terragrunt', 'foo/terragrunt/')
).to be_nil
end

it 'returns nil when the path is shorter than the pattern' do
Expand Down
Loading