chore: update .gitignore and add R2 upload script for artifact management

- Added .automaker/images/ to .gitignore to prevent tracking of generated images.
- Deleted obsolete agent-output.md and feature.json files related to removed "Agent Tools" feature.
- Introduced a new script for uploading build artifacts to R2 and updating releases.json.
- Enhanced GitHub Actions workflow to include artifact uploads for different platforms.
This commit is contained in:
Cody Seibert
2025-12-12 10:39:12 -05:00
parent b950f13e11
commit 813ede2dde
10 changed files with 797 additions and 61 deletions

148
.github/scripts/upload-to-r2.js vendored Normal file
View File

@@ -0,0 +1,148 @@
const { S3Client, PutObjectCommand, GetObjectCommand } = require('@aws-sdk/client-s3');
const fs = require('fs');
const path = require('path');
const s3Client = new S3Client({
region: 'auto',
endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
},
});
const BUCKET = process.env.R2_BUCKET_NAME;
const PUBLIC_URL = process.env.R2_PUBLIC_URL;
const VERSION = process.env.RELEASE_VERSION;
const GITHUB_REPO = process.env.GITHUB_REPOSITORY;
async function fetchExistingReleases() {
try {
const response = await s3Client.send(new GetObjectCommand({
Bucket: BUCKET,
Key: 'releases.json',
}));
const body = await response.Body.transformToString();
return JSON.parse(body);
} catch (error) {
if (error.name === 'NoSuchKey' || error.$metadata?.httpStatusCode === 404) {
console.log('No existing releases.json found, creating new one');
return { latestVersion: null, releases: [] };
}
throw error;
}
}
async function uploadFile(localPath, r2Key, contentType) {
const fileBuffer = fs.readFileSync(localPath);
const stats = fs.statSync(localPath);
await s3Client.send(new PutObjectCommand({
Bucket: BUCKET,
Key: r2Key,
Body: fileBuffer,
ContentType: contentType,
}));
console.log(`Uploaded: ${r2Key} (${stats.size} bytes)`);
return stats.size;
}
function findArtifacts(dir, pattern) {
if (!fs.existsSync(dir)) return [];
const files = fs.readdirSync(dir);
return files.filter(f => pattern.test(f)).map(f => path.join(dir, f));
}
async function main() {
const artifactsDir = 'artifacts';
// Find all artifacts
const artifacts = {
windows: findArtifacts(
path.join(artifactsDir, 'windows-builds'),
/\.exe$/
),
macos: findArtifacts(
path.join(artifactsDir, 'macos-builds'),
/-x64\.dmg$/
),
macosArm: findArtifacts(
path.join(artifactsDir, 'macos-builds'),
/-arm64\.dmg$/
),
linux: findArtifacts(
path.join(artifactsDir, 'linux-builds'),
/\.AppImage$/
),
};
console.log('Found artifacts:');
for (const [platform, files] of Object.entries(artifacts)) {
console.log(` ${platform}: ${files.length > 0 ? files.map(f => path.basename(f)).join(', ') : 'none'}`);
}
// Upload each artifact to R2
const assets = {};
const contentTypes = {
windows: 'application/x-msdownload',
macos: 'application/x-apple-diskimage',
macosArm: 'application/x-apple-diskimage',
linux: 'application/x-executable',
};
for (const [platform, files] of Object.entries(artifacts)) {
if (files.length === 0) {
console.warn(`Warning: No artifact found for ${platform}`);
continue;
}
// Use the first matching file for each platform
const localPath = files[0];
const filename = path.basename(localPath);
const r2Key = `releases/${VERSION}/${filename}`;
const size = await uploadFile(localPath, r2Key, contentTypes[platform]);
assets[platform] = {
url: `${PUBLIC_URL}/releases/${VERSION}/${filename}`,
filename,
size,
arch: platform === 'macosArm' ? 'arm64' : 'x64',
};
}
// Fetch and update releases.json
const releasesData = await fetchExistingReleases();
const newRelease = {
version: VERSION,
date: new Date().toISOString(),
assets,
githubReleaseUrl: `https://github.com/${GITHUB_REPO}/releases/tag/${VERSION}`,
};
// Remove existing entry for this version if re-running
releasesData.releases = releasesData.releases.filter(r => r.version !== VERSION);
// Prepend new release
releasesData.releases.unshift(newRelease);
releasesData.latestVersion = VERSION;
// Upload updated releases.json
await s3Client.send(new PutObjectCommand({
Bucket: BUCKET,
Key: 'releases.json',
Body: JSON.stringify(releasesData, null, 2),
ContentType: 'application/json',
CacheControl: 'public, max-age=60',
}));
console.log('Successfully updated releases.json');
console.log(`Latest version: ${VERSION}`);
console.log(`Total releases: ${releasesData.releases.length}`);
}
main().catch(err => {
console.error('Failed to upload to R2:', err);
process.exit(1);
});

View File

@@ -19,10 +19,13 @@ jobs:
include:
- os: macos-latest
name: macOS
artifact-name: macos-builds
- os: windows-latest
name: Windows
artifact-name: windows-builds
- os: ubuntu-latest
name: Linux
artifact-name: linux-builds
runs-on: ${{ matrix.os }}
@@ -78,3 +81,59 @@ jobs:
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload macOS artifacts for R2
if: matrix.os == 'macos-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: apps/app/dist/*.dmg
retention-days: 1
- name: Upload Windows artifacts for R2
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: apps/app/dist/*.exe
retention-days: 1
- name: Upload Linux artifacts for R2
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: apps/app/dist/*.AppImage
retention-days: 1
upload-to-r2:
needs: build-and-release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Install AWS SDK
run: npm install @aws-sdk/client-s3
- name: Upload to R2 and update releases.json
env:
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
R2_PUBLIC_URL: ${{ secrets.R2_PUBLIC_URL }}
RELEASE_VERSION: ${{ github.event.inputs.version || github.ref_name }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: node .github/scripts/upload-to-r2.js