Skip to content

Commit f6eb2f7

Browse files
swingingsimianNathan Johnsonpditommasoclaude
authored
Fix AzureRepositoryProvider readBytes operation (#6286) [ci fast]
Changed Azure API call from JSON-embedded content to direct binary download using 'download: true' parameter. This prevents binary data corruption that occurred when converting JSON-escaped strings back to bytes. Signed-off-by: Paolo Di Tommaso <[email protected]> Co-authored-by: Nathan Johnson <[email protected]> Co-authored-by: Paolo Di Tommaso <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent a5f8d9b commit f6eb2f7

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

modules/nextflow/src/main/groovy/nextflow/scm/AzureRepositoryProvider.groovy

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,35 @@ final class AzureRepositoryProvider extends RepositoryProvider {
183183
"${config.server}/${urlPath}"
184184
}
185185

186-
/** {@inheritDoc} */
187186
@Override
188-
byte[] readBytes(String path) {
187+
String readText( String path ) {
189188
final url = getContentUrl(path)
190189
final response = invokeAndParseResponse(url)
191-
return response.get('content')?.toString()?.getBytes()
190+
return response.get('content')?.toString()
191+
}
192+
193+
/** {@inheritDoc} */
194+
@Override
195+
byte[] readBytes(String path) {
196+
// For binary content, use direct download instead of JSON embedding
197+
final queryParams = [
198+
'download': true,
199+
'includeContent': false,
200+
'includeContentMetadata': false,
201+
"api-version": 6.0,
202+
'path': path
203+
] as Map<String,Object>
204+
205+
if( revision ) {
206+
queryParams['versionDescriptor.version'] = revision
207+
if( COMMIT_REGEX.matcher(revision).matches() )
208+
queryParams['versionDescriptor.versionType'] = 'commit'
209+
}
210+
211+
final queryString = queryParams.collect({ "$it.key=$it.value"}).join('&')
212+
final url = "$endpointUrl/items?$queryString"
213+
// Use invokeBytes for direct binary content download
214+
return invokeBytes(url)
192215
}
193216

194217
}

modules/nextflow/src/test/groovy/nextflow/cli/CmdConfigTest.groovy

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import nextflow.extension.FilesEx
2424
import nextflow.plugin.Plugins
2525
import nextflow.secret.SecretsLoader
2626
import spock.lang.IgnoreIf
27+
import spock.lang.Requires
2728
import spock.lang.Specification
2829
/**
2930
*
@@ -384,10 +385,12 @@ class CmdConfigTest extends Specification {
384385

385386
}
386387

387-
388388
@IgnoreIf({System.getenv('NXF_SMOKE')})
389+
@Requires({System.getenv('NXF_GITHUB_ACCESS_TOKEN')})
389390
def 'should resolve remote config' () {
390391
given:
392+
SysEnv.push(GITHUB_TOKEN: System.getenv('NXF_GITHUB_ACCESS_TOKEN'))
393+
and:
391394
def buffer = new ByteArrayOutputStream()
392395
def cmd = new CmdConfig(
393396
args: ['https://github.com/nextflow-io/hello'],
@@ -404,6 +407,9 @@ class CmdConfigTest extends Specification {
404407
}
405408
'''
406409
.stripIndent()
410+
411+
cleanup:
412+
SysEnv.pop()
407413
}
408414

409415
@IgnoreIf({System.getenv('NXF_SMOKE')})

modules/nextflow/src/test/groovy/nextflow/scm/AzureRepositoryProviderTest.groovy

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,24 @@ class AzureRepositoryProviderTest extends Specification {
135135
result == 'println "Hello from Azure repos!"'
136136
}
137137

138+
@IgnoreIf({System.getenv('NXF_SMOKE')})
139+
@Requires({System.getenv('NXF_AZURE_REPOS_TOKEN')})
140+
def 'should read bytes file content'() {
141+
given:
142+
def token = System.getenv('NXF_AZURE_REPOS_TOKEN')
143+
def config = new ProviderConfig('azurerepos').setAuth(token)
144+
145+
when:
146+
// uses repo at https://pditommaso.visualstudio.com/nf-azure-repo/_git/nf-azure-repo
147+
def repo = new AzureRepositoryProvider('pditommaso/nf-azure-repo', config)
148+
def result = repo.readBytes('/docs/images/nf-core-rnaseq_logo_light.png')
149+
150+
then:
151+
result.length == 22915
152+
result.sha256() == '7a396344498750f614155f6e4f38b7d6ca98ced45daf0921b64acf73b18efaf4'
153+
}
154+
155+
138156
@IgnoreIf({System.getenv('NXF_SMOKE')})
139157
@Requires({System.getenv('NXF_AZURE_REPOS_TOKEN')})
140158
def 'should fetch repo tags'() {
@@ -170,7 +188,7 @@ class AzureRepositoryProviderTest extends Specification {
170188
result == [
171189
new RepositoryProvider.BranchInfo('dev', 'cc0ca18640a5c995231e22d91f1527d5155d024b'),
172190
new RepositoryProvider.BranchInfo('feature-x', '13456a001ba5a27d643755614ab8e814d94ef888'),
173-
new RepositoryProvider.BranchInfo('master', 'f84130388714582e20f0e2ff9a44b41978ec8929'),
191+
new RepositoryProvider.BranchInfo('master', 'a207636e419f18c4b8c8586b00e329ab4788a7f5'),
174192
]
175193
}
176194

modules/nextflow/src/test/groovy/nextflow/scm/GiteaRepositoryProviderTest.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,19 @@ class GiteaRepositoryProviderTest extends Specification {
106106
result == DATA
107107
}
108108

109+
@IgnoreIf({System.getenv('NXF_SMOKE')})
110+
@Requires({System.getenv('NXF_GITEA_ACCESS_TOKEN')})
111+
def 'should read bytes file content'() {
112+
given:
113+
def token = System.getenv('NXF_GITEA_ACCESS_TOKEN')
114+
def config = new ProviderConfig('gitea', new ConfigSlurper().parse(CONFIG).providers.mygitea as ConfigObject).setAuth(token)
115+
116+
when:
117+
def repo = new GiteaRepositoryProvider('pditommaso/test-hello', config)
118+
def result = repo.readBytes('docs/images/nf-core-rnaseq_logo_light.png')
119+
120+
then:
121+
result.length == 22915
122+
result.sha256() == '7a396344498750f614155f6e4f38b7d6ca98ced45daf0921b64acf73b18efaf4'
123+
}
109124
}

0 commit comments

Comments
 (0)