Skip to content
Snippets Groups Projects
Commit 6c9f9667 authored by Enrique Garcia's avatar Enrique Garcia
Browse files

Merge branch 'codemeta_and_CI_codemeta_utils' into 'master'

update readme and add all new codemeta modifications

See merge request escape2020/wp3/zenodoci!4
parents d91af715 8a053dfa
No related branches found
No related tags found
No related merge requests found
......@@ -26,24 +26,13 @@ deploy_zenodo:
- export REPOSITORY_NAME=zenodoci
- export REPOSITORY_BASE_URL=https://gitlab.in2p3.fr/escape2020/wp3/$REPOSITORY_NAME
- export LAST_RELEASE=`git ls-remote --tags --refs --sort="v:refname" $REPOSITORY_BASE_URL.git | tail -n1 | sed 's/.*\///'`
### 4 - Download the repository and move it to the build directory
### If no release is found/correctly parsed, the script will download the last commit pushed to the master branch
- mkdir -p build
- >
if [ -z "$LAST_RELEASE" ]; then
echo "No tag / new release found ! - Or error when parsing. Downloading last commit to the repository (master branch) ;"; \
wget -O $REPOSITORY_NAME-master.zip "$REPOSITORY_BASE_URL"/-/archive/master/"$REPOSITORY_NAME"-master.zip; \
mv $REPOSITORY_NAME-master.zip ./build
else
echo "$LAST_RELEASE tag / release found !"; \
wget -O $REPOSITORY_NAME-$LAST_RELEASE.zip "$REPOSITORY_BASE_URL"/-/archive/"$LAST_RELEASE"/"$REPOSITORY_NAME"-"$LAST_RELEASE".zip; \
mv $REPOSITORY_NAME-$LAST_RELEASE.zip ./build
fi
- /bin/bash .zenodoci/parse_last_release.sh $REPOSITORY_NAME $REPOSITORY_URL
- ls ./build
script:
### 5 - To deploy a NEW DEPOSIT to ZENODO SANDBOX
- >
......@@ -69,7 +58,7 @@ deploy_zenodo:
# --token $ZENODO_TOKEN
# --sandbox_zenodo False
only:
### Ideally this stage should be run only when a new release / tag of the source code is created (- tags).
### Ideally this stage should be run only when a new release / tag of the source code is created, i.e., (- tags).
# The script is changed to check that the both `upload_new_deposit` and `upload_new_version_deposit` works nicely.
- tags
- master
\ No newline at end of file
- branches # For testing
\ No newline at end of file
from .zenodoapi import *
from .utils_zenodoci import *
from .upload_new_deposit import *
from .upload_new_version_deposit import *
#!/usr/bin/env bash
REPOSITORY_NAME="$1"
REPOSITORY_BASE_URL="$2"
LAST_RELEASE=`git ls-remote --tags --refs --sort="v:refname" $REPOSITORY_BASE_URL.git | tail -n1 | sed 's/.*\///'`
if [ -z "$LAST_RELEASE" ]; then
echo "No tag / new release found ! - Or error when parsing. Downloading last commit to the repository (master branch) ;"
wget -O $REPOSITORY_NAME-master.zip "$REPOSITORY_BASE_URL"/-/archive/master/"$REPOSITORY_NAME"-master.zip
mv $REPOSITORY_NAME-master.zip ./build
else
echo "$LAST_RELEASE tag / release found !"
wget -O $REPOSITORY_NAME-$LAST_RELEASE.zip "$REPOSITORY_BASE_URL"/-/archive/"$LAST_RELEASE"/"$REPOSITORY_NAME"-"$LAST_RELEASE".zip
mv $REPOSITORY_NAME-$LAST_RELEASE.zip ./build
fi
{
"metadata": {
"title": "ZenodoCI",
"upload_type": "software",
"description": "The library is intended to be part of a complete CI pipeline. This stage deploys to Zenodo the files found in the ./build directory, configured in the .gitlab-ci.yml file",
"creators": [{"name": "Garcia, Enrique",
"affiliation": "LAPP, CNRS",
"orcid": "0000-0003-2224-4594"}],
"access_right": "open",
"license": "MIT",
"communities": [{"identifier": "escape2020"}],
"keywords": [],
"language": "eng",
"notes": "Deploy stage (into the Zenodo repository) for a CI (GitLab) pipeline.",
"version": "1.0",
"grants": [{"id": "10.13039/501100000780::824064"}]
}
}
\ No newline at end of file
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import argparse
import requests
......
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# Enrique Garcia. Aug '20
# email garcia 'at' lapp.in2p3.fr
import os
import json
import argparse
from distutils.util import strtobool
from zenodoapi import ZenodoAPI
from utils_zenodoci import (parse_codemeta_and_write_zenodo_metadata_file,
find_root_directory
)
def create_zenodo_metadata(metadata_filename):
"""
Checks for a zenodo metadata file, otherwise it looks for a codemeta.json file to create a the .zenodo.json file
parser = argparse.ArgumentParser(description="Upload new deposit entry to Zenodo")
param metadata_filename: str
path and name to the zenodo metada json file
NOT TO BE CHANGED. The file must be named `.zenodo.json` and be stored in the root directory of the library.
"""
root_dir = find_root_directory()
# Required arguments
parser.add_argument('--token', '-t', type=str,
dest='zenodo_token',
help='Personal access token to (sandbox)Zenodo')
files_json = [file for file in os.listdir(root_dir) if file.endswith('.json')]
print(files_json)
parser.add_argument('--sandbox_zenodo', '-s', action='store',
type=lambda x: bool(strtobool(x)),
dest='sandbox_flag',
help='Set the Zenodo environment.'
'If True connects with Zenodo. If False with Sanbox Zenodo',
default=False)
zenodo_metadata_filename = metadata_filename
codemeta_file = 'codemeta.json'
parser.add_argument('--input-directory', '-i', type=str,
dest='input_directory',
help='Path to the directory containing the files to upload.'
'ALL files will be uploaded.',
required=True)
if codemeta_file in files_json and zenodo_metadata_filename not in files_json:
parse_codemeta_and_write_zenodo_metadata_file(codemeta_file, zenodo_metadata_filename)
print(f"\nCreating {zenodo_metadata_filename} automatically at the CI pipeline.\n")
elif os.path.isfile(zenodo_metadata_filename):
print(f"\n{zenodo_metadata_filename} metadata file found in the root directory of the library ! \n")
pass
else:
print(f"\n{codemeta_file} not found, thus any zenodo_metadata file `{zenodo_metadata_filename}` was"
f" created during the CI pipeline."
f"Please provide one so that the CI can run correctly (examples in the 'codemeta_utils' directory)")
exit(-1)
args = parser.parse_args()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Upload new deposit entry to Zenodo")
z = ZenodoAPI(access_token=args.zenodo_token,
sandbox=args.sandbox_flag # True for sandbox.zenodo.org !! False for zenodo.org
)
# Required arguments
parser.add_argument('--token', '-t', type=str,
dest='zenodo_token',
help='Personal access token to (sandbox)Zenodo')
parser.add_argument('--sandbox_zenodo', '-s', action='store',
type=lambda x: bool(strtobool(x)),
dest='sandbox_flag',
help='Set the Zenodo environment.'
'If True connects with Zenodo. If False with Sanbox Zenodo',
default=False)
parser.add_argument('--input-directory', '-i', type=str,
dest='input_directory',
help='Path to the directory containing the files to upload.'
'ALL files will be uploaded.',
required=True)
args = parser.parse_args()
z = ZenodoAPI(
access_token=args.zenodo_token,
sandbox=args.sandbox_flag # True for sandbox.zenodo.org !! False for zenodo.org
)
# 1 - create empty deposit
new_entry = z.create_new_entry()
......@@ -48,19 +86,27 @@ if __name__ == '__main__':
for file in os.listdir(args.input_directory):
full_path_file = args.input_directory + '/' + file
new_upload = z.upload_file_entry(deposition_id,
name_file=file,
path_file=full_path_file)
new_upload = z.upload_file_entry(
deposition_id,
name_file=file,
path_file=full_path_file
)
print(f"File {file} correctly uploaded !\n", new_upload)
# 3 - Upload repository information - that you must have filled before the json file !
with open('.zenodoci/repository_information.json') as json_file:
entry_info = json.load(json_file)
# 3 - Create the zenodo metadata file from a codemeta.json file
zenodo_metadata_filename = '.zenodo.json'
create_zenodo_metadata(zenodo_metadata_filename)
# And upload the repository metadata
with open(zenodo_metadata_filename) as json_file:
entry_metadata = json.load(json_file)
# entry_info['metadata']['doi'] = doi # In the new version of the API the doi is updated automatically.
update_entry = z.update_info_entry(deposition_id,
data=entry_info)
update_entry = z.update_info_entry(
deposition_id,
data=entry_metadata
)
if update_entry.status_code < 399:
print(f"Status {update_entry.status_code}. Repository information correctly uploaded !")
......
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# Enrique Garcia. Aug '20
# email garcia 'at' lapp.in2p3.fr
import os
import json
import argparse
from distutils.util import strtobool
from zenodoapi import ZenodoAPI
from utils_zenodoci import (parse_codemeta_and_write_zenodo_metadata_file,
find_root_directory
)
parser = argparse.ArgumentParser(description="Upload a new version of an existing deposit to Zenodo")
# Required arguments
parser.add_argument('--token', '-t', type=str,
dest='zenodo_token',
help='Personal access token to (sandbox)Zenodo',
required=True)
def create_zenodo_metadata(metadata_filename):
"""
Checks for a zenodo metadata file, otherwise it looks for a codemeta.json file to create a the .zenodo.json file
parser.add_argument('--sandbox_zenodo', '-s', action='store',
type=lambda x: bool(strtobool(x)),
dest='sandbox_flag',
help='Set the Zenodo environment.'
'If True connects with Zenodo. If False with Sanbox Zenodo',
default=False)
param metadata_filename: str
path and name to the zenodo metada json file
NOT TO BE CHANGED. The file must be named `.zenodo.json` and be stored in the root directory of the library.
"""
root_dir = find_root_directory()
parser.add_argument('--input-directory', '-i', type=str,
dest='input_directory',
help='Path to the directory containing the files to upload.'
'ALL files will be uploaded.',
required=True)
files_json = [file for file in os.listdir(root_dir) if file.endswith('.json')]
print(files_json)
parser.add_argument('--deposit_id', '-id', type=str,
dest='deposit_id',
help='deposit_id of the deposit that is going to be updated by a new version',
required=True)
zenodo_metadata_filename = metadata_filename
codemeta_file = 'codemeta.json'
args = parser.parse_args()
if codemeta_file in files_json and zenodo_metadata_filename not in files_json:
parse_codemeta_and_write_zenodo_metadata_file(codemeta_file, zenodo_metadata_filename)
print(f"\nCreating {zenodo_metadata_filename} automatically at the CI pipeline.\n")
if __name__ == '__main__':
elif os.path.isfile(zenodo_metadata_filename):
print(f"\n{zenodo_metadata_filename} metadata file found in the root directory of the library ! \n")
pass
else:
print(f"\n{codemeta_file} not found, thus any zenodo_metadata file `{zenodo_metadata_filename}` was"
f" created during the CI pipeline."
f"Please provide one so that the CI can run correctly (examples in the 'codemeta_utils' directory)")
exit(-1)
z = ZenodoAPI(access_token=args.zenodo_token,
sandbox=args.sandbox_flag # True for sandbox.zenodo.org !! False for zenodo.org
)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Upload a new version of an existing deposit to Zenodo")
# Required arguments
parser.add_argument('--token', '-t', type=str,
dest='zenodo_token',
help='Personal access token to (sandbox)Zenodo',
required=True)
parser.add_argument('--sandbox_zenodo', '-s', action='store',
type=lambda x: bool(strtobool(x)),
dest='sandbox_flag',
help='Set the Zenodo environment.'
'If True connects with Zenodo. If False with Sanbox Zenodo',
default=False)
parser.add_argument('--input-directory', '-i', type=str,
dest='input_directory',
help='Path to the directory containing the files to upload.'
'ALL files will be uploaded.',
required=True)
parser.add_argument('--deposit_id', '-id', type=str,
dest='deposit_id',
help='deposit_id of the deposit that is going to be updated by a new version',
required=True)
args = parser.parse_args()
z = ZenodoAPI(
access_token=args.zenodo_token,
sandbox=args.sandbox_flag # True for sandbox.zenodo.org !! False for zenodo.org
)
# 1 - request a new version of an existing deposit
new_version = z.new_version_entry(args.deposit_id)
......@@ -49,30 +88,38 @@ if __name__ == '__main__':
new_deposition_id = new_version.json()['links']['latest_draft'].rsplit('/')[-1]
# 2-PRE If you DO NOT want to erase the old files, comment the following lines
# PRE-2 - If you DO NOT want to erase the old files, comment the following lines
old_files_ids = [file['id'] for file in new_version.json()['files']]
for file_id in old_files_ids:
z.erase_file_entry(new_deposition_id,
file_id)
z.erase_file_entry(
new_deposition_id,
file_id
)
# 2 - Upload new version of file(s)
for file in os.listdir(args.input_directory):
full_path_file = args.input_directory + '/' + file
new_upload = z.upload_file_entry(new_deposition_id,
name_file=file,
path_file=full_path_file)
new_upload = z.upload_file_entry(
new_deposition_id,
name_file=file,
path_file=full_path_file
)
print(f"File {file} correctly uploaded !\n", new_upload)
# 3 - Update metadata info
with open('.zenodoci/repository_information.json') as json_file:
update_entry_info = json.load(json_file)
# 3 - Look for a zenodo metadata file, otherwise try to create one
zenodo_metadata_filename = '.zenodo.json'
create_zenodo_metadata(zenodo_metadata_filename)
# update_entry_info['metadata']['doi'] = doi # In the new version of the API the doi is updated automatically.
with open(zenodo_metadata_filename) as json_file:
update_entry_metadata = json.load(json_file)
update_entry = z.update_info_entry(new_deposition_id,
data=update_entry_info)
# update_entry_info['metadata']['doi'] = doi # In the new version of the API the doi is updated automatically.
update_entry = z.update_info_entry(
new_deposition_id,
data=update_entry_metadata
)
if update_entry.status_code < 399:
print(f"Status {update_entry.status_code}. Repository information correctly uploaded !\n")
......
#!/usr/bin/env python
# E. Garcia Nov 20
# email: garcia 'at' lapp.in2p3.fr
import os
import sys
import json
from pathlib import Path
from distutils.util import strtobool
def parse_person_schema_property(person_property, contributor_field):
"""
Parse the Person Schema property correctly
Parameters:
--------
person_property: dict
dictionary codemeta key with the a list or a single Person property item.
contributor_field : str
contributor type {'editor', 'producer', 'sponsor'} or publisher, although the last one can only happen if
`upload_type` is publication (NOT SUPPORTED - contact E. Garcia by email).
Returns:
--------
zenodo_person: dict
dictionary with the correct zenodo syntax for all {author, contributor, maintainer}.
"""
zenodo_person = {}
special_contributor_cases = ['editor', 'producer', 'publisher', 'provider', 'sponsor']
name = person_property['familyName']
if 'givenName' in person_property:
name += f', {person_property["givenName"]}'
zenodo_person['name'] = name
if "@id" in person_property:
if 'orcid.org/' in person_property["@id"]:
# "https://orcid.org/0000-0002-5686-2078" codemeta format not accepted
zenodo_person['orcid'] = person_property["@id"].split('orcid.org/')[-1]
else:
zenodo_person['orcid'] = person_property["@id"]
if "affiliation" in person_property:
zenodo_person['affiliation'] = person_property['affiliation']['name']
# Parse correctly the contributors
if contributor_field in special_contributor_cases:
if contributor_field is 'provider' or contributor_field is 'publisher':
zenodo_person['type'] = 'Other'
else:
try:
zenodo_person['type'] = person_property["type"]
except:
zenodo_person['type'] = contributor_field
return zenodo_person
def add_author_metadata(zenodo_file, codemt_file, field):
"""
Aux function to parse correctly all the authors, contributors and maintainers that can be found at the
codemeta.json file
zenodo_file: dict
metadata dictionary with the zenodo syntax
codem_file: list or dict
metadata dictionary key field with the codemeta syntax
field: str
codemeta key field specifying creator {author, contributor, maintainer, creator}, or
contributors {editor, sponsor, producer, project manager...}
"""
full_contacts = {}
creators_fields = ['author', 'creator', 'maintainer', 'contributor']
contributors_fields = ['editor', 'producer', 'publisher', 'provider', 'sponsor']
# First create the full contact agenda by field
if type(codemt_file[field]) is list:
for person_property in codemt_file[field]:
zenodo_person = parse_person_schema_property(person_property, field)
# 'name' is the only key that MUST be contained in a person_property at least
full_contacts[zenodo_person['name']] = zenodo_person
else:
zenodo_person = parse_person_schema_property(codemt_file[field], field)
full_contacts[zenodo_person['name']] = zenodo_person
# then save each person by field and avoid duplicates
for i, person in enumerate(full_contacts):
if field in creators_fields:
# Contributors and maintainers in the same zenodo key
if i == 0 and 'creators' not in zenodo_file:
zenodo_file['creators'] = []
elif person not in zenodo_file['creators']:
zenodo_file['creators'].append(full_contacts[person])
else:
pass # avoid duplicates
elif field in contributors_fields:
if i == 0 and 'contributors' not in zenodo_file:
zenodo_file['contributors'] = []
elif person not in zenodo_file['contributors']:
zenodo_file['contributors'].append(full_contacts[person])
else:
pass # avoid duplicates
def find_matching_metadata(codemeta_json):
"""
Please note that the following fields are ASSUMED. If they are not correct, change them, or contact us otherwise.
"access_right": "open"
"language": "eng"
param codemeta_json: dict
already parsed dictionary containing the metadata of the codemeta.json file
Returns:
--------
metadata_zenodo : dict
dictionary cotaining the metadata information found at the codemeta.json file but written using the Zenodo
syntax.
"""
person_filed = ['author', 'creator', 'maintainer', 'contributor', 'editor', 'producer', 'publisher',
'provider', 'sponsor']
metadata_zenodo = {'language': 'eng',
'access_right': 'open'}
if codemeta_json["@type"] == "SoftwareSourceCode":
metadata_zenodo['upload_type'] = 'software'
else:
metadata_zenodo['upload_type'] = ''
print("\nCould not identify the type of schema in the `codemeta.json file`.\n"
"Thus the 'upload_type' within the `.zenodo.json` file was left EMPTY.\n"
"Please fill it up by yourself - otherwise zenodo will NOT be able to publish your entry.\n")
if 'name' in codemeta_json:
metadata_zenodo['title'] = codemeta_json['name']
if 'description' in codemeta_json:
metadata_zenodo['description'] = codemeta_json['description']
if 'softwareVersion' in codemeta_json and 'version' not in codemeta_json:
metadata_zenodo['version'] = codemeta_json['softwareVersion']
elif 'version' in codemeta_json and 'softwareVersion' not in codemeta_json:
metadata_zenodo['version'] = codemeta_json['version']
else:
metadata_zenodo['version'] = codemeta_json['version']
if 'keywords' in codemeta_json:
if type(codemeta_json['keywords']) == list:
metadata_zenodo['keywords'] = codemeta_json['keywords']
else:
metadata_zenodo['keywords'] = [codemeta_json['keywords']]
if 'license' in codemeta_json:
metadata_zenodo['license'] = codemeta_json['license'].split('/')[-1]
if 'releaseNotes' in codemeta_json:
metadata_zenodo['notes'] = "Release Notes: " + codemeta_json['releaseNotes']
if 'citation' in codemeta_json:
metadata_zenodo['references'] = codemeta_json['citation']
if 'datePublished' in codemeta_json:
metadata_zenodo['publication_date'] = codemeta_json['datePublished']
for person in person_filed:
if person in codemeta_json:
add_author_metadata(metadata_zenodo, codemeta_json, field=person)
return metadata_zenodo
def add_compulsory_escape_metadata(json_file):
"""
Add compulsory information to the .zenodo.json file:
* zenodo community : ESCAPE2020
* ESCAPE grant ID (zenodo syntax)
param json_file: dict
dictionary containing the .zenodo.json metadata information
"""
json_file["communities"] = [{"identifier": "escape2020"}]
json_file["grants"] = [{"id": "10.13039/501100000780::824064"}]
def parse_codemeta_and_write_zenodo_metadata_file(codemeta_filename, zenodo_outname):
"""
Reads the codemeta.json file and creates a new `.zenodo.json` file. This file will contain the SAME information
that in the codemeta.json file but *** WITH THE ZENODO SYNTAX. ***
codemeta_filename: str or Path
path to the codemeta.json file
zenodo_outname: str or Path
path and name to the zenodo metada json file
NOT TO BE CHANGED. The file must be named `.zenodo.json` and be stored in the root directory of the library.
"""
with open(codemeta_filename) as infile:
codemeta_json = json.load(infile)
metadata_zenodo = find_matching_metadata(codemeta_json)
add_compulsory_escape_metadata(metadata_zenodo)
# Correct format for Zenodo
data = {'metadata': metadata_zenodo}
with open(zenodo_outname, 'w') as outfile:
json.dump(data, outfile, indent=4, sort_keys=True)
def query_yes_no(question, default="yes"):
"""
Ask a yes/no question via raw_input() and return their answer.
:param question: str
question to the user
:param default: str - "yes", "no" or None
resumed answer if the user just hits <Enter>.
"yes" or "no" will set a default answer for the user
None will require a clear answer from the user
:return: bool - True for "yes", False for "no"
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
else:
try:
return bool(strtobool(choice))
except:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
def query_continue(question, default="no"):
"""
Ask a question and if the answer is no, exit the program.
Calls `query_yes_no`.
:param question: str
:param default: str
:return answer: bool - answer from query_yes_no
"""
answer = query_yes_no(question, default=default)
if not answer:
sys.exit("Program stopped by user")
else:
return answer
def find_root_directory():
"""
Find root directory of the project. This library MUST be added to the root directory of the same, i.e., MUST be
a subdirectory of the root dir.
:return root_directory: obj
Path object with root directory
"""
current_dir = os.path.abspath(os.path.dirname(__file__))
current_dir_name = current_dir.split('/')[-1]
root_directory = Path(str(current_dir.split(current_dir_name)[0]))
return root_directory
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# E. Garcia
# email: garcia 'at' lapp.in2p3.fr
import json
import requests
......
......@@ -12,8 +12,8 @@ Library to manage an upload to Zenodo through its REST API.
The library was developed specifically to perform a deploy stage (to the Zenodo repository) in a GitLab CI
pipeline that **could be implemented in any external project**.
It provides a module to handle the upload of
specified file(s) to the [ESCAPE2020 Zenodo community](https://zenodo.org/communities/escape2020/).
It provides a module to handle the upload of the desired
file(s) to the [ESCAPE2020 Zenodo community](https://zenodo.org/communities/escape2020/).
Please **only upload stable versions/releases of source code and/or image containers!**
The `deploy` stage in the CI pipeline (see the `.gitlab-ci.yml` file) will make use of the `zenodoapi` library and
......@@ -23,10 +23,32 @@ https://gitlab.in2p3.fr/escape2020/wp3/template_project_escape)
- Either upload the desired file(s) to the ESCAPE community in Zenodo.
- Either upload a new version of an existing entry to Zenodo.
The `repository_information.json` file must be filled up before pushing to the GitLab repository. This file will be
used to fill up the compulsory information that a Zenodo entry must contain. Also, depending on the case, the
corresponding python script (`upload_new_deposit.py` or `upload_new_version_of_deposit.py`) must be adapted and
included into the `.gitlab-ci.yml` file with its corresponding arguments (examples are shown in the yml file).
A `codemeta.json` metadata file (see below) **MUST BE ADDED** before uploading an entry to Zenodo or triggering the GitLabCI pipeline.
Also, depending on the case, the corresponding python script (`upload_new_deposit.py` or `upload_new_version_of_deposit.py`)
must be adapted and included into the `.gitlab-ci.yml` file with its corresponding arguments (examples are shown in the yml file).
You need a more detailed tutorial ? Please check our more detailed tutorials at the [OSSR entry point site](
https://escape2020.pages.in2p3.fr/wp3/ossr-pages/page/repository/publish_in_repository/).
Problems creating a `.gitlab-ci.yml` file ? Please check the `gitlab_generator` module implemented in [this ESCAPE project](
https://gitlab.in2p3.fr/escape2020/wp3/template_project_escape/-/tree/master/gitlabci_generator).
#### **Use of new metadata context ! Please check the news !**
We are no longer supporting the use of a `repository_information.json` file to provide metadata to Zenodo.
We are currently moving to a [CodeMeta metadata context](https://codemeta.github.io/).
This metadata standard provides a complete metadata schema context supported by many other services and search engines.
Adding a single `codemeta.json` file to the root directory of your project will be enough ! Please check out the
[ESCAPE metadata template](https://gitlab.in2p3.fr/escape2020/wp3/escape_metadata_template) project for a _quickstart_ on
how to easily create a `codemeta.json` file.
Last but not least ! Please note that during the CI pipeline the `.zenodoci` module will search for a `codemeta.json` file
and will automatically create the equivalent file to provide metadata to the Zenodo repository. The `.zenodo.json` file
will contain the exactly same information that in the `codemeta.json` file but using the Zenodo syntax.
### Zenodo token & GitLab CI environment variable
......@@ -45,5 +67,10 @@ your personal token, you should create an environment variable in your GitLab re
The environment variable will look like this:
```sh
$ python .zenodoci/upload_new_deposit.py -i build -t $ZENODO_TOKEN -s False
```
\ No newline at end of file
$ python .zenodoci/upload_new_deposit.py --input-directory build --token $ZENODO_TOKEN --sandbox_zenodo False
```
## Contact
[Contact us](mailto:garcia@lapp.in2p3.fr) for any question or doubt related with the current library, the ESCAPE project,
the metadata schema context or the integration of any project to Zenodo, Gitlab or the ESCAPE OSSR.
\ No newline at end of file
{
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"@type": "SoftwareSourceCode",
"name": "ZenodoCI",
"description": "The library is intended to be part of a complete CI pipeline. This stage deploys to Zenodo the files found in the ./build directory, configured in the .gitlab-ci.yml file",
"keywords": [],
"license": "https://spdx.org/licenses/MIT",
"softwareVersion": "1.0",
"developmentStatus": "active",
"codeRepository": "https://gitlab.in2p3.fr/escape2020/wp3/zenodoci",
"runtimePlatform": "Python >3.6",
"downloadUrl": "https://gitlab.in2p3.fr/escape2020/wp3/zenodoci/-/archive/v1.0/zenodoci-v1.0.tar.gz",
"installUrl": "https://escape2020.pages.in2p3.fr/wp3/ossr-pages/page/repository/publish_in_repository/",
"releaseNotes": "Deploy stage (into the Zenodo repository) for a CI pipeline",
"dateCreated": "2020-06-31",
"datePublished": "2020-06-31",
"dateModified": "2020-10-24",
"isAccessibleForFree": true,
"isPartOf": [
"https://gitlab.in2p3.fr/escape2020",
"https://gitlab.in2p3.fr/escape2020/wp3",
"https://zenodo.org/communities/escape2020",
"https://projectescape.eu/"
],
"contIntegration": "https://gitlab.in2p3.fr/escape2020/wp3/zenodoci/-/pipelines",
"buildInstructions": "https://escape2020.pages.in2p3.fr/wp3/ossr-pages/page/repository/publish_in_repository/",
"issueTracker": "https://gitlab.in2p3.fr/escape2020/wp3/zenodoci/-/issues",
"readme": "https://gitlab.in2p3.fr/escape2020/wp3/zenodoci/-/blob/master/README.md",
"programmingLanguage": [
{
"@type": "ComputerLanguage",
"name": "Python",
"url": "https://www.python.org/"
},
{
"@type": "ComputerLanguage",
"name": "Bash",
"url": "https://www.gnu.org/software/bash/"
}
],
"softwareRequirements": [
{
"@type": "SoftwareApplication",
"identifier": "numpy",
"name": "numpy",
"softwareVersion": "1.18.1"
},
{
"@type": "SoftwareApplication",
"identifier": "requests",
"name": "requests",
"softwareVersion": ">=2.23"
},
{
"@type": "SoftwareApplication",
"identifier": "pyjson",
"name": "json",
"softwareVersion": ">=1.3.0"
},
{
"@type": "SoftwareApplication",
"identifier": "pyyaml",
"name": "pyyaml",
"softwareVersion": ">=5.3.1"
}
],
"maintainer": {
"@type": "Person",
"@id": "https://orcid.org/0000-0003-2224-4594",
"givenName": "Enrique",
"familyName": "Garcia",
"email": "garcia@lapp.in2p3.fr",
"affiliation": {
"@type": "Organization",
"name": "LAPP, CNRS"
}
},
"author": [
{
"@type": "Person",
"@id": "https://orcid.org/0000-0003-2224-4594",
"givenName": "Enrique",
"familyName": "Garcia",
"email": "garcia@lapp.in2p3.fr",
"affiliation": {
"@type": "Organization",
"name": "LAPP, CNRS"
}
}
],
"contributor": [
{
"@type": "Person",
"@id": "https://orcid.org/0000-0002-5686-2078",
"givenName": "Thomas",
"familyName": "Vuillaume",
"email": "vuillaume@lapp.in2p3.fr",
"affiliation": {
"@type": "Organization",
"name": "LAPP, CNRS"
}
}
],
"funder":[
{
"@type": "Organization",
"@id": "https://doi.org/10.13039/501100000780",
"name": "European Commission"
},
{
"@type": "Organization",
"name": "ESCAPE: European Science Cluster of Astronomy & Particle physics ESFRI research infrastructures",
"funder": {
"@type": "Organization",
"@id": "https://doi.org/10.13039/501100000780",
"name": "European Commission"
}
}
],
"funding": "824064"
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment