MCPcopy Create free account
hub / github.com/github/gh-aw / validateBlockScalarExpressionSizes

Function validateBlockScalarExpressionSizes

pkg/workflow/runtime_validation.go:110–179  ·  view source on GitHub ↗

validateBlockScalarExpressionSizes scans the YAML lines for multi-line block scalars (literal | or folded >) and returns an error when any such block both contains a GitHub Actions template expression (${{ }}) and exceeds maxSize bytes in total.

(lines []string, maxSize int)

Source from the content-addressed store, hash-verified

108// (literal | or folded >) and returns an error when any such block both contains a
109// GitHub Actions template expression (${{ }}) and exceeds maxSize bytes in total.
110func validateBlockScalarExpressionSizes(lines []string, maxSize int) error {
111 // Track whether we are inside a block scalar and its metadata.
112 inBlock := false
113 blockKey := ""
114 blockStartLine := 0
115 blockIndent := -1
116 blockSize := 0
117 blockHasExpression := false
118
119 checkBlock := func() error {
120 if inBlock && blockHasExpression && blockSize > maxSize {
121 actualSize := console.FormatFileSize(int64(blockSize))
122 maxSizeFormatted := console.FormatFileSize(int64(maxSize))
123 return fmt.Errorf("expression value for %q (%s) exceeds maximum allowed size (%s) starting at line %d. "+
124 "GitHub Actions has a 21KB limit for YAML values that contain template expressions (${{ }}). "+
125 "Split the step into separate run: blocks so that no single block containing ${{ }} expressions exceeds the limit",
126 blockKey, actualSize, maxSizeFormatted, blockStartLine+1)
127 }
128 return nil
129 }
130
131 for i, line := range lines {
132 // Count leading spaces to determine indentation level.
133 trimmed := strings.TrimLeft(line, " \t")
134 indent := len(line) - len(trimmed)
135
136 if inBlock {
137 // An empty line is part of the block (blank lines are allowed inside block scalars).
138 if strings.TrimSpace(line) == "" {
139 blockSize += len(line) + 1 // +1 for the newline
140 continue
141 }
142 // A line whose indentation is greater than the block header's indentation
143 // is still inside the block scalar.
144 if indent > blockIndent {
145 blockSize += len(line) + 1
146 if strings.Contains(line, "${{") {
147 blockHasExpression = true
148 }
149 continue
150 }
151 // Indentation dropped back – the block has ended.
152 if err := checkBlock(); err != nil {
153 return err
154 }
155 inBlock = false
156 blockKey = ""
157 blockSize = 0
158 blockHasExpression = false
159 blockIndent = -1
160 }
161
162 // Detect the start of a block scalar: a YAML key whose value is | or >
163 // e.g. " run: |" or " script: >"
164 if colonIdx := strings.Index(trimmed, ":"); colonIdx > 0 {
165 afterColon := strings.TrimSpace(trimmed[colonIdx+1:])
166 if afterColon == "|" || afterColon == ">" || strings.HasPrefix(afterColon, "|-") || strings.HasPrefix(afterColon, ">-") {
167 inBlock = true

Calls 2

FormatFileSizeFunction · 0.92
ErrorfMethod · 0.45

Tested by 1