From a280ee787edfc773d8b6a49ba0a0abe03359172a Mon Sep 17 00:00:00 2001 From: DrRetro2033 Date: Mon, 23 Dec 2024 10:04:09 -0500 Subject: [PATCH] Added Cider for version increment, and created a release script. --- CHANGELOG.md | 4 +- pubspec.lock | 8 +++ pubspec.yaml | 8 ++- scripts/release.dart | 141 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 scripts/release.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index effe43c..fdc774d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0 +# 0.0.1-alpha -- Initial version. +This is the first alpha version of Arceus. \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index e4a1b29..1cebaa3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -262,6 +262,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.6.0" + http: + dependency: "direct dev" + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" http_multi_server: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 861ede0..6c08235 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: arceus description: A sample command-line application with basic argument parsing. -version: 0.0.1 +version: 0.0.1-alpha # repository: https://github.com/my_org/my_repo environment: @@ -28,6 +28,7 @@ dev_dependencies: lints: ^4.0.0 test: ^1.24.0 ffigen: ^16.0.0 + http: ^1.2.2 ffigen: # Run with `flutter pub run ffigen --config ffigen.yaml`. @@ -54,3 +55,8 @@ ffigen: structs: rename: "_(.*)": "$1" # Removes prefix underscores from all structures. + +cider: + link_template: + tag: https://github.com/DrRetro2033/Arceus/releases/tag/%tag% # initial release link template + diff: https://github.com/DrRetro2033/Arceus/compare/%from%...%to% # subsequent releases link template diff --git a/scripts/release.dart b/scripts/release.dart new file mode 100644 index 0000000..6204ef8 --- /dev/null +++ b/scripts/release.dart @@ -0,0 +1,141 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:http/http.dart' as http; +import 'package:yaml/yaml.dart'; + +Future main(List args) async { + // Configuration + const repoOwner = 'DrRetro2033'; // Replace with your GitHub username or org + const repoName = 'Arceus'; // Replace with your repository name + + final apiBase = 'https://api.github.com/repos/$repoOwner/$repoName'; + final token = String.fromEnvironment('GITHUB_TOKEN'); + if (args.isEmpty) { + print('Usage: dart release.dart '); + exit(1); + } + final pathOfProject = args.first; + if (!Directory(pathOfProject).existsSync()) { + print('Error: Directory not found: $pathOfProject'); + exit(1); + } + final downloadedFiles = []; // List of downloaded artifacts + try { + // Step 1: Fetch the most recent workflow run + print('Fetching latest workflow run...'); + final workflowsResponse = await http.get( + Uri.parse('$apiBase/actions/runs'), + headers: {'Authorization': 'token $token'}, + ); + + if (workflowsResponse.statusCode != 200) { + throw Exception( + 'Failed to fetch workflow runs: ${workflowsResponse.body}'); + } + + final workflowsData = jsonDecode(workflowsResponse.body); + final latestRun = workflowsData['workflow_runs']?.first; + if (latestRun == null) { + throw Exception('No workflow runs found.'); + } + + final runId = latestRun['id']; + print('Latest workflow run ID: $runId'); + + // Step 2: Fetch artifacts from the latest run + print('Fetching artifacts...'); + final artifactsResponse = await http.get( + Uri.parse('$apiBase/actions/runs/$runId/artifacts'), + headers: {'Authorization': 'token $token'}, + ); + + if (artifactsResponse.statusCode != 200) { + throw Exception('Failed to fetch artifacts: ${artifactsResponse.body}'); + } + + final artifactsData = jsonDecode(artifactsResponse.body)['artifacts']; + if (artifactsData.isEmpty) { + throw Exception('No artifacts found for the latest workflow run.'); + } + + // Download artifacts + for (final artifact in artifactsData) { + final artifactId = artifact['id']; + final artifactName = artifact['name']; + print('Downloading artifact: $artifactName...'); + + final artifactDownloadResponse = await http.get( + Uri.parse('$apiBase/actions/artifacts/$artifactId/zip'), + headers: {'Authorization': 'token $token'}, + ); + + if (artifactDownloadResponse.statusCode != 200) { + throw Exception( + 'Failed to download artifact: ${artifactDownloadResponse.body}'); + } + + final outputFile = File('$artifactName.zip'); + await outputFile.writeAsBytes(artifactDownloadResponse.bodyBytes); + downloadedFiles.add(outputFile); + print('Artifact downloaded: ${outputFile.path}'); + } + + // Step 3: Create a release + print('Creating release...'); + final createReleaseResponse = await http.post( + Uri.parse('$apiBase/releases'), + headers: { + 'Authorization': 'token $token', + 'Content-Type': 'application/json', + }, + body: jsonEncode({ + 'tag_name': + 'v${loadYaml(File("$pathOfProject/pubspec.yaml").readAsStringSync())['version']}', + 'name': + 'v${loadYaml(File("$pathOfProject/pubspec.yaml").readAsStringSync())['version']}', + 'body': File('$pathOfProject/CHANGELOG.md').readAsStringSync(), + 'draft': true, + 'prerelease': true, + }), + ); + + if (createReleaseResponse.statusCode != 201) { + throw Exception( + 'Failed to create release: ${createReleaseResponse.body}'); + } + + final releaseData = jsonDecode(createReleaseResponse.body); + final uploadUrl = + releaseData['upload_url'].toString().replaceAll('{?name,label}', ''); + + print('Release created: ${releaseData['html_url']}'); + + // Step 4: Upload artifacts to the release + for (final file in downloadedFiles) { + print('Uploading artifact: ${file.path}...'); + final uploadResponse = await http.post( + Uri.parse( + '$uploadUrl?name=${Uri.encodeComponent(file.uri.pathSegments.last)}'), + headers: { + 'Authorization': 'token $token', + 'Content-Type': 'application/octet-stream', + }, + body: await file.readAsBytes(), + ); + + if (uploadResponse.statusCode != 201) { + throw Exception('Failed to upload artifact: ${uploadResponse.body}'); + } + + final uploadedAsset = jsonDecode(uploadResponse.body); + print('Artifact uploaded: ${uploadedAsset['browser_download_url']}'); + } + + print('Release process completed successfully!'); + } catch (e) { + print('Error: $e'); + } + for (File downloadedFile in downloadedFiles) { + downloadedFile.deleteSync(); + } +}