1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
- import fs from 'fs';
- import yaml from 'js-yaml';
- import path from 'path';
- /**
- * Represents the structure of package.json file
- */
- interface PackageJson {
- license: string;
- version: string;
- description: string;
- }
- /**
- * Represents the structure of CITATION.cff file
- */
- interface Citation {
- 'cff-version': string;
- message: string;
- authors: Array<{
- 'family-names': string;
- 'given-names': string;
- }>;
- title: string;
- version: string;
- 'date-released': string;
- url: string;
- 'repository-code': string;
- license: string;
- type: string;
- description: string;
- keywords: string[];
- }
- /**
- * Creates a default Citation object with information from package.json
- * @param packageJson - The parsed package.json file
- * @returns A default Citation object
- */
- const createDefaultCitation = (packageJson: PackageJson): Citation => ({
- 'cff-version': '1.2.0',
- message: 'If you use this software, please cite it as below.',
- authors: [
- {
- 'family-names': 'Webster',
- 'given-names': 'Ian',
- },
- ],
- title: 'promptfoo',
- version: packageJson.version,
- 'date-released': new Date().toISOString().slice(0, 10),
- url: 'https://promptfoo.dev',
- 'repository-code': 'https://github.com/promptfoo/promptfoo',
- license: packageJson.license,
- type: 'software',
- description: packageJson.description,
- keywords: ['llm', 'evaluation', 'evals', 'testing', 'prompt-engineering', 'red-team'],
- });
- /**
- * Fetches the release date for a specific version from GitHub
- * @param version The version to fetch the release date for
- * @returns Promise<string> The release date in ISO format, or null if not found
- */
- async function getReleaseDate(version: string): Promise<string | null> {
- try {
- const response = await fetch(
- `https://api.github.com/repos/promptfoo/promptfoo/releases/tags/${version}`,
- );
- if (!response.ok) {
- if (response.status === 404) {
- console.warn(`No release found for version ${version}`);
- return null;
- }
- throw new Error(`GitHub API request failed: ${response.statusText}`);
- }
- const data = await response.json();
- return data.published_at ? new Date(data.published_at).toISOString().slice(0, 10) : null;
- } catch (error) {
- console.error(`Error fetching release date for version ${version}:`, error);
- return null;
- }
- }
- /**
- * Updates the CITATION.cff file with the latest information from package.json and GitHub
- * @throws {Error} If there's an issue reading or writing files
- */
- export const updateCitation = async (): Promise<void> => {
- const packageJsonPath: string = path.join(__dirname, '../package.json');
- const citationPath: string = path.join(__dirname, '../CITATION.cff');
- const packageJson: PackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
- let citation: Citation;
- try {
- citation = yaml.load(fs.readFileSync(citationPath, 'utf8')) as Citation;
- } catch {
- citation = createDefaultCitation(packageJson);
- }
- citation['version'] = packageJson.version;
- const releaseDate = await getReleaseDate(packageJson.version);
- citation['date-released'] = releaseDate || new Date().toISOString().slice(0, 10);
- fs.writeFileSync(citationPath, yaml.dump(citation, { lineWidth: -1 }));
- console.log('CITATION.cff file has been updated.');
- };
- if (require.main === module) {
- updateCitation().catch(console.error);
- }
|