Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: ♻️ πŸ” πŸ”Š πŸ§‘β€πŸ’» Add Environment Variables and Convert Logging to Use Logwatch #120

Merged
merged 53 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0767e2c
refactor: :recycle: transfer validation api to codefair repo (#106)
slugb0t Nov 16, 2024
be75575
🚚 chore: rename `validator-api` to `validator`
megasanjay Nov 16, 2024
8e3b3a4
πŸ‘· ci: add validator deploy
megasanjay Nov 16, 2024
aba85b3
πŸ‘· ci: add validator healthcheck
megasanjay Nov 16, 2024
242bde1
πŸ‘· ci: add validator deploy for prod
megasanjay Nov 16, 2024
303824b
refactor: :recycle: update codefair name
slugb0t Nov 22, 2024
96d4e82
feat: ✨ Metadata + license validators + bug patches (#107)
slugb0t Dec 2, 2024
9219131
fix: :bug: use the correct env variable for private key
slugb0t Dec 2, 2024
76c35b7
fix: πŸ› Codefair v3.2.0 finalization (#113)
slugb0t Dec 9, 2024
95dad9c
fix: :bug: migrate db during deployment
slugb0t Dec 9, 2024
f570d2d
fix: :bug: revert
slugb0t Dec 9, 2024
4db16dd
fix: :bug: typo on dockerfile
slugb0t Dec 9, 2024
10de0d5
refactor: :recycle: use npm instead of yarn for migration
slugb0t Dec 9, 2024
408a242
refactor: :recycle: access db url during prisma build
slugb0t Dec 9, 2024
b3b75f6
refactor: :recycle: apply node env
slugb0t Dec 9, 2024
e97beb0
πŸ’š ci: copy package json
megasanjay Dec 9, 2024
2c5b413
πŸ’š ci: revert arg
megasanjay Dec 9, 2024
a3f891d
πŸ’š ci: add prisma migrate to ci
megasanjay Dec 9, 2024
c0b0540
πŸ’š ci: add prisma migrate to ci
megasanjay Dec 9, 2024
fd0b979
πŸ‘· ci: update dockerfile
megasanjay Dec 9, 2024
561169d
refactor: :recycle: use deployed validator
slugb0t Dec 9, 2024
027c86d
Merge branch 'staging' of https://github.com/fairdataihub/codefair-ap…
slugb0t Dec 9, 2024
29c0617
fix: :bug: when license is updated validate metadata files
slugb0t Dec 9, 2024
a86c6ca
fix: :bug: validation returns codemeta version on errors
slugb0t Dec 9, 2024
dd9718e
πŸ› fix: add basic logwatch
megasanjay Dec 9, 2024
1f51519
fix: :bug: add @type key for 2.0 codemeta.json files
slugb0t Dec 9, 2024
25bc54b
Merge branch 'staging' of https://github.com/fairdataihub/codefair-ap…
slugb0t Dec 9, 2024
c940a7b
refactor: :recycle: updated required fields for codemeta schmea
slugb0t Dec 9, 2024
6036f5a
πŸ› fix: add logwatch support
megasanjay Dec 9, 2024
c13e7a6
πŸ› fix: add json to logwatch
megasanjay Dec 9, 2024
82baf3f
fix: :bug: patch json parse issue
slugb0t Dec 9, 2024
d4c2335
Merge branch 'staging' of https://github.com/fairdataihub/codefair-ap…
slugb0t Dec 9, 2024
e4428f2
fix: :bug: update logging parameters
slugb0t Dec 9, 2024
e648184
refactor: :recycle: point a folder above for codemeta-schema
slugb0t Dec 9, 2024
771699d
refactor: :recycle: update dockerfile to include schema
slugb0t Dec 10, 2024
104ae3e
fix: :bug: ensure authors have roles key
slugb0t Dec 10, 2024
4132e66
refactor: :recycle: :loud_sound: convert some consola logs to logwatch
slugb0t Dec 10, 2024
6fedd07
fix: :bug: roles are optional in save request
slugb0t Dec 10, 2024
808b93b
chore: :loud_sound: remove dev logs
slugb0t Dec 10, 2024
8edc800
doc: :memo: update changelog
slugb0t Dec 10, 2024
a878891
refactor: :recycle: revert roles key being optional
slugb0t Dec 10, 2024
7ba12b6
fix: :bug: add logwatch.start method
slugb0t Dec 10, 2024
cde62bd
fix: :bug: ensure contrib and authros have roles
slugb0t Dec 10, 2024
4bca8d3
Merge branch 'main' into staging
slugb0t Dec 10, 2024
619880e
fix: :bug: CWL handles multiple installations
slugb0t Dec 10, 2024
6fe2edb
refactor: :recycle: update log error
slugb0t Dec 10, 2024
7393750
merge: :twisted_rightwards_arrows: remote-tracking branch 'origin/mai…
slugb0t Dec 10, 2024
4c77ab1
feat: :sparkles: purge zenodo token when sign in is required
slugb0t Dec 11, 2024
5bffc66
fix: :bug: make login fn asyncronous
slugb0t Dec 11, 2024
ddc15c7
refactor: :art: update spacing and color of validation results button
slugb0t Dec 11, 2024
5d0e835
fix: :bug: bad logwatch call removed
slugb0t Dec 11, 2024
b7f37c0
chore: πŸ”¨ sync main to staging (#118)
slugb0t Dec 11, 2024
f10eae4
refactor: ♻️ πŸ” πŸ”Š πŸ§‘β€πŸ’» Add Environment Variables and Convert Logging to…
slugb0t Dec 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/deploy-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }}
KAMAL_BOT_DOMAIN: ${{ secrets.KAMAL_BOT_DOMAIN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BOT_LOGWATCH_URL: ${{ secrets.BOT_LOGWATCH_URL }}
APP_ID: ${{ secrets.APP_ID }}
GH_APP_ID: ${{ secrets.GH_APP_ID }}
GH_APP_NAME: ${{ secrets.GH_APP_NAME }}
Expand All @@ -36,6 +37,7 @@ jobs:
CODEFAIR_APP_DOMAIN: ${{ secrets.CODEFAIR_APP_DOMAIN }}
ZENODO_API_ENDPOINT: ${{ secrets.ZENODO_API_ENDPOINT }}
ZENODO_ENDPOINT: ${{ secrets.ZENODO_ENDPOINT }}
VALIDATOR_URL: ${{ secrets.VALIDATOR_URL }}

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -99,6 +101,7 @@ jobs:
GH_OAUTH_APP_ID: ${{ secrets.GH_OAUTH_APP_ID }}
GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
UI_LOGWATCH_URL: ${{ secrets.UI_LOGWATCH_URL }}
ZENODO_API_ENDPOINT: ${{ secrets.ZENODO_API_ENDPOINT }}
ZENODO_ENDPOINT: ${{ secrets.ZENODO_ENDPOINT }}
ZENODO_CLIENT_ID: ${{ secrets.ZENODO_CLIENT_ID }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
KAMAL_SERVER_IP: ${{ secrets.KAMAL_SERVER_IP }}
KAMAL_BOT_DOMAIN: ${{ secrets.KAMAL_BOT_DOMAIN }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BOT_LOGWATCH_URL: ${{ secrets.BOT_LOGWATCH_URL }}
APP_ID: ${{ secrets.APP_ID }}
GH_APP_ID: ${{ secrets.GH_APP_ID }}
GH_APP_NAME: ${{ secrets.GH_APP_NAME }}
Expand All @@ -36,6 +37,7 @@ jobs:
CODEFAIR_APP_DOMAIN: ${{ secrets.CODEFAIR_APP_DOMAIN }}
ZENODO_API_ENDPOINT: ${{ secrets.ZENODO_API_ENDPOINT }}
ZENODO_ENDPOINT: ${{ secrets.ZENODO_ENDPOINT }}
VALIDATOR_URL: ${{ secrets.VALIDATOR_URL }}

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -99,6 +101,7 @@ jobs:
GH_OAUTH_APP_ID: ${{ secrets.GH_OAUTH_APP_ID }}
GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
UI_LOGWATCH_URL: ${{ secrets.UI_LOGWATCH_URL }}
ZENODO_API_ENDPOINT: ${{ secrets.ZENODO_API_ENDPOINT }}
ZENODO_ENDPOINT: ${{ secrets.ZENODO_ENDPOINT }}
ZENODO_CLIENT_ID: ${{ secrets.ZENODO_CLIENT_ID }}
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes the Codefair App will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## v3.2.1 - 12-12-2024

### Added

- Convert logging from 'consola' to 'logwatch' for improved log management and consistency across the application.

### Fixed

- Update CI and deployment workflows to include new environment variables 'BOT_LOGWATCH_URL' and 'VALIDATOR_URL'.
- Patch to Zenodo workflow that was causing the user to be notified of a failed Zenodo upload when the upload was successful.

## v3.2.0 - 12-10-2024

### Added
Expand Down
10 changes: 5 additions & 5 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ authors:
cff-version: 1.2.0
message: If you use this software, please cite it using the metadata from this file.
type: software
doi: 10.5281/zenodo.14064362
abstract:
doi: 10.5281/zenodo.14400138
abstract: >-
Codefair is a free and open source GitHub app that acts as your personal
assistant when it comes to making your research software reusable and
especially complying with the Findable, Accessible, Interoperable, Reusable
(FAIR) Principles for Research Software (FAIR4RS Principles). Whether you are
developing artificial intelligence (AI)/machine learning (ML) models with
Python, data visualization tools with Jupyter notebook, or data analysis code
with R, Codefair is here to assist you.
with R, Codefair is here to assist you.
keywords:
- best-practices
- fair
Expand All @@ -32,5 +32,5 @@ keywords:
- software
license: MIT
repository-code: https://github.com/fairdataihub/codefair-app
date-released: '2024-11-11'
version: 3.1.1
date-released: '2024-12-11'
version: 3.2.0
2 changes: 2 additions & 0 deletions bot/.kamal/secrets
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ KAMAL_SERVER_IP=$KAMAL_SERVER_IP
# bot secrets
APP_ID=$APP_ID
DATABASE_URL=$DATABASE_URL
BOT_LOGWATCH_URL=$BOT_LOGWATCH_URL
GH_APP_ID=$GH_APP_ID
GH_APP_NAME=$GH_APP_NAME
GH_APP_CLIENT_ID=$GH_APP_CLIENT_ID
Expand All @@ -24,6 +25,7 @@ WEBHOOK_SECRET=$WEBHOOK_SECRET
CODEFAIR_APP_DOMAIN=$CODEFAIR_APP_DOMAIN
ZENODO_API_ENDPOINT=$ZENODO_API_ENDPOINT
ZENODO_ENDPOINT=$ZENODO_ENDPOINT
VALIDATOR_URL=$VALIDATOR_URL

# Option 2: Read secrets via a command
# RAILS_MASTER_KEY=$(cat config/master.key)
Expand Down
40 changes: 20 additions & 20 deletions bot/archival/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dbInstance from '../db.js';
import { consola } from 'consola';
import { logwatch } from '../utils/logwatch.js';
import fs from 'fs';
const licensesJson = JSON.parse(fs.readFileSync('./public/assets/data/licenses.json', 'utf8'));

Expand All @@ -20,7 +21,7 @@ export async function updateGitHubRelease(context, repositoryName, owner, releas
release_id: releaseId,
draft: false,
});
consola.success("Updated release to not be a draft!");
logwatch.success("Updated release to not be a draft!");
} catch (error) {
throw new Error(`Error updating the GitHub release: ${error}`, { cause: error });
}
Expand All @@ -33,7 +34,7 @@ export async function updateGitHubRelease(context, repositoryName, owner, releas
*/
export async function publishZenodoDeposition(zenodoToken, depositionId) {
try {
consola.start("Publishing the Zenodo deposition...", depositionId);
logwatch.start(`Publishing the Zenodo deposition: ${depositionId}`);
const publishDeposition = await fetch(
`${ZENODO_API_ENDPOINT}/deposit/depositions/${depositionId}/actions/publish`,
{
Expand All @@ -50,7 +51,7 @@ export async function publishZenodoDeposition(zenodoToken, depositionId) {
}

const publishedDeposition = await publishDeposition.json();
consola.success("Zenodo deposition published successfully at:", publishedDeposition.links.latest_html);
logwatch.success(`Zenodo deposition published successfully at: ${publishedDeposition.links.latest_html}`);
} catch (error) {
throw new Error(`Error publishing the Zenodo deposition: ${error.message}`, { cause: error });
}
Expand Down Expand Up @@ -251,7 +252,7 @@ export async function createNewVersionOfDeposition(zenodoToken, depositionId) {
const errorText = await zenodoRecord.text();
throw new Error(`Failed to create a new version of Zenodo deposition. Status: ${zenodoRecord.status}: ${zenodoRecord.statusText}.`, { cause: errorText});
}
consola.success("New version of Zenodo deposition created successfully!");
logwatch.success("New version of Zenodo deposition created successfully!");

const responseText = await zenodoRecord.json();

Expand All @@ -265,7 +266,7 @@ export async function createNewVersionOfDeposition(zenodoToken, depositionId) {
});

if (!draftZenodoRecord.ok) {
consola.error("Error fetching the latest draft of Zenodo deposition:", draftZenodoRecord);
logwatch.error({message: "Error fetching the latest draft of Zenodo deposition:", fetchReponse: draftZenodoRecord}, true);
const errorText = await draftZenodoRecord.text();
throw new Error(`Failed to fetch the latest draft of Zenodo deposition. Status: ${draftZenodoRecord.status}: ${draftZenodoRecord.statusText}. Error: ${errorText}`, { cause: errorText });
}
Expand Down Expand Up @@ -295,7 +296,7 @@ export async function getZenodoDepositionInfo(

if (zenodoDepositionInfo.submitted === false){
// Delete the files in the draft
consola.start("Requested deposition is a draft. Deleting the files in the draft...");
logwatch.start("Requested deposition is a draft. Deleting the files in the draft...");
for (const file of zenodoDepositionInfo.files) {
await deleteFileFromZenodo(depositionId, zenodoToken, file.id);
}
Expand All @@ -307,12 +308,12 @@ export async function getZenodoDepositionInfo(

if (newZenodoVersion.files.length > 0) {
for (const file of newZenodoVersion.files) {
consola.start("Deleting file from newly created draft:", file.links.download);
logwatch.start(`Deleting file from newly created draft: ${file.links.download}`);
await deleteFileFromZenodo(newZenodoVersion.id, zenodoToken, file.id);
}
}

consola.success("New draft version of Zenodo deposition created successfully!");
logwatch.success("New draft version of Zenodo deposition created successfully!");
return newZenodoVersion;
}
}
Expand Down Expand Up @@ -354,8 +355,8 @@ export async function createZenodoMetadata(codemetadata, repository) {
});
if (!codeMetaContent.license) {
// fetch from the db
consola.warn(`No license found in the codemeta.json file. Fetching from the database...`);
consola.info(`License found in the database: ${existingLicense?.license_id}`);
logwatch.warn(`No license found in the codemeta.json file. Fetching from the database...`);
logwatch.info(`License found in the database: ${existingLicense?.license_id}`);
codeMetaContent.license = `https://spdx.org/licenses/${existingLicense?.license_id}`;
}
const license = licensesJson.find((license) => license.detailsUrl === `${codeMetaContent.license}.json`);
Expand All @@ -372,7 +373,7 @@ export async function createZenodoMetadata(codemetadata, repository) {
})

if (!zenodoMetadata) {
consola.error("Zenodo metadata not found in the database. Please create a new Zenodo deposition.");
logwatch.error("Zenodo metadata not found in the database. Please create a new Zenodo deposition.");
throw new Error("Zenodo metadata not found in the database. Please create a new Zenodo deposition.");
}

Expand Down Expand Up @@ -440,7 +441,7 @@ export async function updateZenodoMetadata(depositionId, zenodoToken, metadata)
);

const updatedMetadataInfo = await updatedMetadata.json();
consola.success("Zenodo deposition metadata updated successfully!");
logwatch.success("Zenodo deposition metadata updated successfully!");
return updatedMetadataInfo;
} catch (error) {
throw new Error(`Error updating Zenodo metadata: ${error}`, { cause: error });
Expand Down Expand Up @@ -480,7 +481,7 @@ export async function uploadReleaseAssetsToZenodo(
accept: 'application/octet-stream'
}
});
consola.success(`Asset data fetched for ${asset.name}, for the release ${tagVersion}, from the GitHub repository: ${repository.name}`);
logwatch.success(`Asset data fetched for ${asset.name}, for the release ${tagVersion}, from the GitHub repository: ${repository.name}`);

// Upload the file to Zenodo
const uploadAsset = await fetch(`${bucket_url}/${asset.name}`,
Expand All @@ -493,9 +494,9 @@ export async function uploadReleaseAssetsToZenodo(
});

if (!uploadAsset.ok) {
consola.error(`Failed to upload ${asset.name}. Status: ${uploadAsset.statusText}. Error: ${uploadAsset}`);
logwatch.error(`Failed to upload ${asset.name}. Status: ${uploadAsset.statusText}. Error: ${uploadAsset}`);
} else {
consola.success(`${asset.name} successfully uploaded to Zenodo!`);
logwatch.success(`${asset.name} successfully uploaded to Zenodo!`);
}
} catch (error) {
throw new Error(`Error uploading assets to Zenodo: ${error}`, { cause: error });
Expand All @@ -516,13 +517,13 @@ export async function uploadReleaseAssetsToZenodo(
);

if (!uploadZip.ok) {
consola.error(`Failed to upload zip file. Status: ${uploadZip.statusText}`);
logwatch.error(`Failed to upload zip file. Status: ${uploadZip.statusText}`);
throw new Error(`Failed to upload zip file. Status: ${uploadZip.statusText}`);
}

const endTime = performance.now();
consola.info(`Total duration to upload assets and zip to Zenodo deposition: ${(endTime - startTime) / 1000} seconds`);
consola.success("Zip file successfully uploaded to Zenodo!");
logwatch.info(`Total duration to upload assets and zip to Zenodo deposition: ${(endTime - startTime) / 1000} seconds`);
logwatch.success("Zip file successfully uploaded to Zenodo!");
}

/**
Expand All @@ -543,12 +544,11 @@ export async function deleteFileFromZenodo(depositionId, zenodoToken, fileId) {
);

if (!deleteFile.ok) {
consola.error(deleteFile);
const errorText = await deleteFile.text();
throw new Error(`Failed to delete file from Zenodo. Status: ${deleteFile.status}: ${deleteFile.statusText}. Error: ${errorText}`);
}

consola.success("File successfully deleted from Zenodo!");
logwatch.success("File successfully deleted from Zenodo!");
} catch (error) {
throw new Error(`Error deleting file from Zenodo: ${error}`, { cause: error });
}
Expand Down
2 changes: 2 additions & 0 deletions bot/config/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ env:
- CODEFAIR_APP_DOMAIN
- ZENODO_API_ENDPOINT
- ZENODO_ENDPOINT
- VALIDATOR_URL
- BOT_LOGWATCH_URL
clear:
NODE_ENV: production

Expand Down
Loading
Loading