uploadBuild method
Future<void>
uploadBuild({
- required AutoRefreshingAuthClient authClient,
- required String buildLocation,
Implementation
Future<void> uploadBuild({
required final AutoRefreshingAuthClient authClient,
required final String buildLocation,
}) async {
stdout.writeln('Creating version...');
final versionResponse = await authClient.post(
Uri(
scheme: 'https',
host: 'firebasehosting.googleapis.com',
path: 'v1beta1/sites/$_projectId/versions',
),
headers: {'Content-Type': 'application/json'},
);
if (versionResponse.statusCode != 200) {
logHttpResponse(versionResponse);
throw Exception('Error creating version.');
}
final versionData =
json.decode(versionResponse.body) as Map<String, dynamic>;
final versionName = versionData['name'] as String;
stdout.writeln('Populating release...');
final fileMap = <String, String>{};
await for (final file
in Directory('build/web').list(recursive: true, followLinks: false)) {
if (file is File) {
final fileBytes = await file.readAsBytes();
final compressedBytes = GZipCodec().encode(fileBytes);
final compressedHash = sha256.convert(compressedBytes).toString();
final relativePath = file.path.replaceFirst('build/web/', '');
final filePath = '/$relativePath';
fileMap[filePath] = compressedHash;
}
}
final populateResponse = await authClient.post(
Uri.parse(
'https://firebasehosting.googleapis.com/v1beta1/$versionName:populateFiles',
),
headers: {'Content-Type': 'application/json'},
body: json.encode({'files': fileMap}),
);
if (populateResponse.statusCode != 200) {
logHttpResponse(populateResponse);
throw Exception('Error populating release.');
}
final releaseData =
json.decode(populateResponse.body) as Map<String, dynamic>;
final uploadUrl = releaseData['uploadUrl'];
final uploadRequiredHashes = releaseData['uploadRequiredHashes'];
stdout.writeln('Uploading files...');
final uploadTasks = <Future>[];
for (final hash in uploadRequiredHashes) {
final filePath =
fileMap.entries.firstWhere((final entry) => entry.value == hash).key;
final file = File('build/web$filePath');
final fileBytes = await file.readAsBytes();
final compressedBytes = GZipCodec().encode(fileBytes);
final uploadTask = authClient
.put(
Uri.parse('$uploadUrl/$hash'),
headers: {'Content-Type': 'application/octet-stream'},
body: compressedBytes,
)
.then((final response) {
if (response.statusCode == 200) {
stdout.writeln('File $filePath uploaded successfully.');
} else {
logHttpResponse(response);
}
});
uploadTasks.add(uploadTask);
}
await Future.wait(uploadTasks);
stdout.writeln('All files uploaded. Finalizing deployment...');
final finalizeResponse = await authClient.patch(
Uri.parse(
'https://firebasehosting.googleapis.com/v1beta1/$versionName?update_mask=status',
),
headers: {'Content-Type': 'application/json'},
body: json.encode({
'status': 'FINALIZED',
}),
);
if (finalizeResponse.statusCode != 200) {
logHttpResponse(finalizeResponse);
throw Exception('Error finalizing deployment.');
}
stdout.writeln('Releasing...');
final releaseResponse = await authClient.post(
Uri(
scheme: 'https',
host: 'firebasehosting.googleapis.com',
path: 'v1beta1/sites/$_projectId/releases',
queryParameters: {
'versionName': versionName,
},
),
headers: {'Content-Type': 'application/json'},
);
if (releaseResponse.statusCode != 200) {
logHttpResponse(releaseResponse);
throw Exception('Error releasing version.');
}
stdout.writeln('🎉 Deployment completed successfully!\n'
'Deployed to: https://$_projectId.web.app');
}