diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5a5a5ecafa65be7c50f7f67f1426bca3826a3e8..19327fe5d69027acf77d329f7f31b605b8cd6865 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,35 +2,65 @@ stages: - build_and_tests - fmt - clippy + - package + - prerelease - publish before_script: - export PATH="$HOME/.cargo/bin:$PATH" + +variables: + CARGO_HOME: $CI_PROJECT_DIR/cargo + + +.rust_stable_env: &rust_stable_env + tags: + - redshift-rs-stable + before_script: + - export PATH="$HOME/.cargo/bin:$PATH" + - rustc --version && cargo --version + +.rust_beta_env: &rust_beta_env + tags: + - redshift-rs-beta + before_script: + - export PATH="$HOME/.cargo/bin:$PATH" + - rustup update + - rustc --version && cargo --version + +.rust_nightly_env: &rust_nightly_env + image: rustlang/rust:nightly + tags: + - redshift-rs-nightly + before_script: + - export PATH="$HOME/.cargo/bin:$PATH" + - rustc --version && cargo --version build_and_tests:stable: + <<: *rust_stable_env stage: build_and_tests tags: - redshift-rs-stable script: - cargo build --features strict - cargo test --all + cache: + paths: + - cargo/ + - target/ build_and_tests:beta: + <<: *rust_beta_env stage: build_and_tests - tags: - - redshift-rs-beta script: - - rustup update - cargo build --features strict - cargo test --all when: manual allow_failure: true build_and_tests:nightly: + <<: *rust_nightly_env stage: build_and_tests - image: rustlang/rust:nightly - tags: - - redshift-rs-nightly script: - cargo build --features strict - cargo test --all @@ -38,49 +68,100 @@ build_and_tests:nightly: allow_failure: true fmt: + <<: *rust_nightly_env stage: fmt - image: rustlang/rust:nightly - tags: - - redshift-rs-nightly before_script: - - export PATH="$HOME/.cargo/bin:$PATH" - cargo install --force rustfmt-nightly script: - cargo fmt -- --check allow_failure: true clippy: + <<: *rust_nightly_env stage: clippy - image: rustlang/rust:nightly - tags: - - redshift-rs-nightly before_script: - - export PATH="$HOME/.cargo/bin:$PATH" - cargo install --force clippy --verbose script: - cargo clippy --all -- -D warnings --verbose allow_failure: true +package:test:linux-x64: + <<: *rust_stable_env + stage: package + script: + - bash "release/arch/linux-x64/build-lin-x64.sh" "$(date +%Y%m%d).$(date +%H%M).$(date +%S)" + cache: + paths: + - cargo/ + - target/ + artifacts: + paths: + - work/bin/ + expire_in: 1 weeks + except: + - tags + when: manual + +package:prod:linux-x64: + <<: *rust_stable_env + stage: package + script: + - bash "release/arch/linux-x64/build-lin-x64.sh" "${CI_COMMIT_TAG#v}" + cache: + paths: + - cargo/ + - target/ + artifacts: + paths: + - work/bin/ + expire_in: 2 weeks + only: + - dev + - tags + +.release_jobs: &release_jobs + image: tensorflow/tensorflow:latest-py3 + tags: + - redshift-rs + script: + - python3 .gitlab/releaser + only: + - dev + - tags + +prerelease: + <<: *release_jobs + stage: prerelease + variables: + RELEASE_BIN_DIR: work/bin/ + SOURCE_EXT: '["tar.gz", "zip"]' + +publish:release: + <<: *release_jobs + stage: publish + variables: + RELEASE_BIN_DIR: work/bin/ + WIKI_RELEASE: Releases + allow_failure: false + when: manual + publish:crate: + <<: *rust_stable_env stage: publish - tags: - - redshift-rs-stable script: - IFS='/' read -r first a <<< "$CI_COMMIT_TAG" - cd $first - cargo login $DUNITER_CRATES_TOKEN - cargo publish only: + - publish-crate - tags allow_failure: false when: manual pages: + <<: *rust_stable_env stage: publish - tags: - - redshift-rs-stable - before_script: - - export PATH="$HOME/.cargo/bin:$PATH" script: - cargo doc - mv target/doc public @@ -90,4 +171,6 @@ pages: paths: - public allow_failure: true - when: manual \ No newline at end of file + when: manual + only: + - dev \ No newline at end of file diff --git a/.gitlab/release_template.md b/.gitlab/release_template.md new file mode 100644 index 0000000000000000000000000000000000000000..adc0470e572edb7f8b37ba7bf1730c710da15ef4 --- /dev/null +++ b/.gitlab/release_template.md @@ -0,0 +1,34 @@ +{% block prerelease %} +# :gift: Pre-release + +[Go to Pipeline page :arrow_forward:](https://git.duniter.org/nodes/rust/duniter-rs/pipelines/{{pipeline}}) + +{% endblock %} + +{% block release %} +# :white_check_mark: Release + +{% endblock %} + +{% block notebody %} +<placeholder content="end-title" /> +<placeholder content="note"> +{{current_message}} +</placeholder> + +## Downloads + +| Category | Arch | Type | Size | File | +|----------|------|------|------|------| +{% for artifact in artifacts %} +| {{artifact.category}} | {{artifact.arch}} | {{artifact.type}} | {{artifact.size}} | [{{artifact.icon}} {{artifact.name}}]({{artifact.url}}) | +{% endfor %} +{% endblock %} + +{% block previouswiki %} + + +## {{tag}} + +{{body}} +{% endblock %} diff --git a/.gitlab/releaser/__init__.py b/.gitlab/releaser/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4f0a11e46162aa197c5f61768335d949955ae02b --- /dev/null +++ b/.gitlab/releaser/__init__.py @@ -0,0 +1,12 @@ +''' +This module is meant add release notes in gitlab for the current project. +Expects to find in environment following variables: + - CI_PROJECT_URL - Automatically set by gitlab-ci + - CI_PROJECT_ID - Automatically set by gitlab-ci + - CI_COMMIT_TAG - Automatically set by gitlab-ci + - CI_PIPELINE_ID - Automatically set by gitlab-ci + - RELEASE_BIN_DIR - Directory where releases are to be found + - SOURCE_EXT - Source extensions (pre-release only) + - WIKI_RELEASE - Wiki page where releases are stored (release only) + - RELEASER_TOKEN - Token used by technical user +''' diff --git a/.gitlab/releaser/__main__.py b/.gitlab/releaser/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..83a061b83f7f74905faeee23b9fa4702ffe3ab11 --- /dev/null +++ b/.gitlab/releaser/__main__.py @@ -0,0 +1,3 @@ +from releaser import Releaser + +Releaser().release() diff --git a/.gitlab/releaser/artifact.py b/.gitlab/releaser/artifact.py new file mode 100644 index 0000000000000000000000000000000000000000..e0d37f33a7d6896b471a708bf20a5c9e43ce8082 --- /dev/null +++ b/.gitlab/releaser/artifact.py @@ -0,0 +1,84 @@ +class Artifact: + ''' + An artifact to be uploaded. + ''' + + def __init__(self, file_name, category, arch, dtype, icon): + ''' + :param file_name: The name of the artifact file (may have directory). + :param category: The category (OS, distrib) for the artifact. + :param arch: The architecture name. + :param dtype: The delivery type (either server or desktop). + :param icon: The name of the icon to be used for artifact representation. + :type file_name: str + :type category: str + :type arch: str + :type dtype: str + :type icon: str + ''' + self.file_name = file_name + self.category = category + self.arch = arch + self.dtype = dtype + self.icon = icon + + def __lt__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category < other.category or \ + (self.category == other.category and self.arch < other.arch) or \ + (self.category == other.category and self.arch == other.arch and self.dtype < other.dtype) + + def __le__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category <= other.category or \ + (self.category == other.category and self.arch <= other.arch) or \ + (self.category == other.category and self.arch == other.arch and self.dtype <= other.dtype) + + def __eq__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category == other.category and self.arch == other.arch and self.dtype == other.dtype + + def __ne__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category != other.category or self.arch != other.arch or self.dtype != other.dtype + + def __gt__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category > other.category or \ + (self.category == other.category and self.arch > other.arch) or \ + (self.category == other.category and self.arch == other.arch and self.dtype > other.dtype) + + def __ge__(self, other): + if not isinstance(other, Artifact): raise TypeError() + return self.category >= other.category or \ + (self.category == other.category and self.arch >= other.arch) or \ + (self.category == other.category and self.arch == other.arch and self.dtype >= other.dtype) + + def to_dict(self): + ''' + :return: A dictionnary containing artifact data. + :rtype: dict + ''' + return { + 'name': self.file_name.split('/')[-1], + 'category': self.category, + 'arch': self.arch, + 'type': self.dtype, + 'url': self._build_url(), + 'size': self._get_size(), + 'icon': ':{}:'.format(self.icon) + } + + def _get_size(self): + ''' + :return: The size of the artifact. + :rtype: FSItemSize + ''' + raise NotImplementedError() + + def _build_url(self): + ''' + :return: The URL which can be used to get this artifact. + :rtype: str + ''' + raise NotImplementedError() diff --git a/.gitlab/releaser/binartifact.py b/.gitlab/releaser/binartifact.py new file mode 100644 index 0000000000000000000000000000000000000000..cc3ab04e05fa1386e93d745ff610dd5ea9def5a4 --- /dev/null +++ b/.gitlab/releaser/binartifact.py @@ -0,0 +1,37 @@ +import json +import os + +from artifact import Artifact +from fsitemsize import FSItemSize + +class BinArtifact(Artifact): + ''' + A binary artifact. + ''' + + def __init__(self, folder, desc_file, desc_ext): + ''' + :param folder: The folder where files can be found. + :param desc_file: The name of the description file. + :param desc_ext: The extention of the description file. + :type folder: str + :type desc_file: str + :type desc_ext: str + ''' + try: + description = json.load(open(desc_file)) + except json.decoder.JSONDecodeError: + print('CRITICAL Description file {} could not be read'.format(desc_file)) + exit(1) + + self.tag = description['version'] + self.job = description['job'] + file_name = desc_file[:-len(desc_ext)] + Artifact.__init__(self, file_name, description['category'], description['arch'], description['type'], 'package') + + def _get_size(self): + return FSItemSize(int(os.path.getsize(self.file_name))) + + def _build_url(self): + return '{}/-/jobs/{}/artifacts/raw/{}'.format( + os.environ['CI_PROJECT_URL'], self.job, self.file_name) diff --git a/.gitlab/releaser/fsitemsize.py b/.gitlab/releaser/fsitemsize.py new file mode 100644 index 0000000000000000000000000000000000000000..a6c8be232cdaf2ae00cebef732c225c27b427a3c --- /dev/null +++ b/.gitlab/releaser/fsitemsize.py @@ -0,0 +1,28 @@ +import math + +class FSItemSize: + ''' + The size of a file system item. + ''' + + def __init__(self, bsize = None): + ''' + :param bsize: Size of item in bytes. + :type bsize: int + ''' + self.bsize = bsize + + def __str__(self): + ''' + :return: Human readable size. + :rtype: str + ''' + if self.bsize is None: + return '(unknown)' + elif self.bsize == 0: + return '0 B' + size_name = ('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB') + i = int(math.floor(math.log(self.bsize, 1024))) + power = math.pow(1024, i) + size = round(self.bsize / power, 2) + return '{} {}'.format(size, size_name[i]) diff --git a/.gitlab/releaser/job.py b/.gitlab/releaser/job.py new file mode 100644 index 0000000000000000000000000000000000000000..2dc55c08fcb14a76074b597b81f892a8aa339646 --- /dev/null +++ b/.gitlab/releaser/job.py @@ -0,0 +1,22 @@ +import urllib.request + +from projectapi import ProjectApi + +class Job(ProjectApi): + ''' + Job data API. + ''' + + def __init__(self, job_id): + ''' + :param job_id: The job id. + :type job_id: int + ''' + ProjectApi.__init__(self, '/jobs/{}'.format(job_id)) + + def keep_artifacts(self): + ''' + Force artifacts to be kept forever. + ''' + request = self.build_request('/artifacts/keep', method='POST') + urllib.request.urlopen(request) diff --git a/.gitlab/releaser/placeholder.py b/.gitlab/releaser/placeholder.py new file mode 100644 index 0000000000000000000000000000000000000000..a3624f0b3b94ac494f3451820fbbb2ec127aba9a --- /dev/null +++ b/.gitlab/releaser/placeholder.py @@ -0,0 +1,120 @@ +class PlaceHolder: + ''' + Placeholder tags in Markdown texts. + ''' + __PLACEHOLDER_PART = '<placeholder' + __PLACEHOLDER_START = '<placeholder content="{}">' + __PLACEHOLDER_STOP = '</placeholder>' + __PLACEHOLDER_FULL = '<placeholder content="{}" />' + + def __init__(self, content_id): + ''' + :param content_id: The identifier to be used for placeholder content. + :type content_id: str + ''' + self.ph_start = PlaceHolder.__PLACEHOLDER_START.format(content_id) + self.ph_stop = PlaceHolder.__PLACEHOLDER_STOP + self.ph_full = PlaceHolder.__PLACEHOLDER_FULL.format(content_id) + + def get_content(self, text): + ''' + :param text: The text in which to extract content. + :type text: str + :return: The content between placeholder markers. + :rtype: str + ''' + pos = text.find(self.ph_start) + if pos >= 0: + text = text[pos + len(self.ph_start):] + pos = text.find(self.ph_stop) + if pos >= 0: text = text[:pos] + return text + + def get_before(self, text, keep_mark=False): + ''' + :param text: The text in which to extract content. + :param keep_mark: If true, the mark is kept in final text. + :type text: str + :type keep_mark: bool + :return: The content before (full) placeholder marker. + :rtype: str + ''' + pos = text.find(self.ph_full) + if pos >= 0: + if keep_mark: pos += len(self.ph_full) + text = text[:pos] + return text + + def get_after(self, text, keep_mark=False): + ''' + :param text: The text in which to extract content. + :param keep_mark: If true, the mark is kept in final text. + :type text: str + :type keep_mark: bool + :return: The content after (full) placeholder marker. + :rtype: str + ''' + pos = text.find(self.ph_full) + if pos >= 0: + if not keep_mark: pos += len(self.ph_full) + text = text[pos:] + return text + + def replace_content(self, text, content): + ''' + :param text: The text in which to extract content. + :param content: The new content to insert. + :type text: str + :type content: str + :return: The text where content has been replaced. + :rtype: str + ''' + pos = text.find(self.ph_start) + if pos >= 0: + pos += len(self.ph_start) + text_before = text[:pos] + else: + pos = 0 + text_before = '' + pos = text.find(self.ph_stop, pos) + if pos >= 0: + text_after = text[pos:] + else: + text_after = '' + return text_before + content + text_after + + def insert_after(self, text, content): + ''' + :param text: The text in which to extract content. + :param content: The new content to insert. + :type text: str + :type content: str + :return: The text where content has been inserted. + :rtype: str + ''' + pos = text.find(self.ph_full) + if pos >= 0: pos += len(self.ph_full) + else: pos = 0 + text_before = text[:pos] + text_after = text[pos:] + return text_before + content + text_after + + def clear_all(text): + ''' + Clear all placeholders from given text. + :param text: The text to clear. + :type text: str + :return: The clean text. + :rtype: str + ''' + while True: + pos = text.find(PlaceHolder.__PLACEHOLDER_PART) + if pos < 0: break + end = text.find('>') + if end < 0: end = len(text) + text = text[:pos] + text[end + 1:] + while True: + pos = text.find(PlaceHolder.__PLACEHOLDER_STOP) + if pos < 0: break + text = text[:pos] + text[pos + len(PlaceHolder.__PLACEHOLDER_STOP):] + return text diff --git a/.gitlab/releaser/projectapi.py b/.gitlab/releaser/projectapi.py new file mode 100644 index 0000000000000000000000000000000000000000..eea07e769b95af92960e6538d7f2af60f3c699e8 --- /dev/null +++ b/.gitlab/releaser/projectapi.py @@ -0,0 +1,31 @@ +import os +import urllib.request + +class ProjectApi: + ''' + Gitlab API project access. + ''' + __PROJECT_URL = 'https://git.duniter.org/api/v4/projects/{}' + + def __init__(self, url=''): + ''' + :param url: The URL portion to add to base project URL (if needed). + :type url: str + ''' + self.base_url = ProjectApi.__PROJECT_URL.format(os.environ['CI_PROJECT_ID']) + self.base_url += url + self.token = ('Private-Token', os.environ['RELEASER_TOKEN']) + + def build_request(self, url='', **params): + ''' + Create the request to send to project API. + :param url: The portion of URL to add to base URL (if needed). + :param params: The optional parameters. + :type url: str + :type params: dict + :return: The request, ready to be used. + :rtype: urllib.request.Request + ''' + request = urllib.request.Request(self.base_url + url, **params) + request.add_header(*self.token) + return request diff --git a/.gitlab/releaser/releasenote.py b/.gitlab/releaser/releasenote.py new file mode 100644 index 0000000000000000000000000000000000000000..c4fff9a756273d38fed03907fb585e3db7fa90b1 --- /dev/null +++ b/.gitlab/releaser/releasenote.py @@ -0,0 +1,74 @@ +import json +import os +import urllib.request + +from placeholder import PlaceHolder +from projectapi import ProjectApi + +class ReleaseNote(ProjectApi): + ''' + Release note API. + ''' + __PH_TITLE = PlaceHolder('end-title') + __PH_NOTE = PlaceHolder('note') + + def __init__(self): + ProjectApi.__init__(self, '/repository/tags/{}'.format(os.environ['CI_COMMIT_TAG'])) + self.message_read = False + + def get_note(self): + ''' + Get full release note. + :return: The note if it exists, None otherwise. + :rtype: str or None + ''' + request = self.build_request() + response = urllib.request.urlopen(request) + response_data = response.read().decode() + data = json.loads(response_data) + if data['release'] is None: + return None + else: + self.message_read = True + return data['release']['description'] + + def get_message(self): + ''' + Get release message. Message is extracted from full note. + :return: The message if it exists, empty string otherwise. + :rtype: str + ''' + data = self.get_note() + if data is None: + return '' + else: + return ReleaseNote.__PH_NOTE.get_content(data) + + def get_note_body(self): + ''' + Get release note body (without title). Body is extracted from full note. + :return: The body. + :rtype: str + ''' + data = self.get_note() + if data is None: + print('CRITICAL No release information to publish') + exit(1) + return ReleaseNote.__PH_TITLE.get_after(data, True) + + def send_note(self, note): + ''' + Send the full release note. The current message should have been read + unless you are sure there are none. + :param note: The full note to send. + :type note: str + ''' + method = 'PUT' if self.message_read else 'POST' + send_data = { + 'tag_name': os.environ['CI_COMMIT_TAG'], + 'description': note + } + send_data_serialized = json.dumps(send_data).encode('utf-8') + request = self.build_request('/release', data=send_data_serialized, method=method) + request.add_header('Content-Type', 'application/json') + urllib.request.urlopen(request) diff --git a/.gitlab/releaser/releaser.py b/.gitlab/releaser/releaser.py new file mode 100644 index 0000000000000000000000000000000000000000..dca04456186c0c187cdb899c67ee6f8dd58c5429 --- /dev/null +++ b/.gitlab/releaser/releaser.py @@ -0,0 +1,107 @@ +import glob +import jinja2 +import json +import os + +from binartifact import BinArtifact +from job import Job +from placeholder import PlaceHolder +from releasenote import ReleaseNote +from releasewikipage import ReleaseWikiPage +from sourceartifact import SourceArtifact +from template import Template + +class Releaser: + ''' + The main releaser class + ''' + + def __init__(self): + self.template = Template('release_template.md') + if 'RELEASE_BIN_DIR' in os.environ: + self.release_bin_dir = os.environ['RELEASE_BIN_DIR'] + if not self.release_bin_dir.endswith('/'): self.release_bin_dir += '/' + else: + print('CRITICAL RELEASE_BIN_DIR environment variable not set') + exit(1) + if 'SOURCE_EXT' in os.environ: + self.source_ext = os.environ['SOURCE_EXT'] + try: + self.source_ext = json.loads(self.source_ext) + except json.decoder.JSONDecodeError: + print('CRITICAL SOURCE_EXT environment variable JSON probably malformed') + print('CRITICAL Correct : \'["zip","tar.gz"]\' ') + print('CRITICAL Not Correct: "[\'zip\',\'tar.gz\']" ') + exit(1) + else: self.source_ext = None + + def release(self): + if self.source_ext is None: + self.publish_release() + else: + self.publish_prerelease() + + def publish_prerelease(self): + ''' + Main job to publish a pre-release. + ''' + releaseNote = ReleaseNote() + current_message = releaseNote.get_message() + artifacts_list = [] + + # Get releases + artifacts_list += self._get_bin_artifacts() + artifacts_list.sort() + artifacts_list += list(map(lambda e: SourceArtifact(e), self.source_ext)) + + # Send result + note = self.template.render('notebody', { + 'current_message': current_message, + 'artifacts': list(map(lambda a: a.to_dict(), artifacts_list)) + }) + title_line = self.template.render('prerelease', { + 'tag': os.environ['CI_COMMIT_TAG'], + 'pipeline': os.environ['CI_PIPELINE_ID'] + }) + releaseNote.send_note(title_line + note) + + print('Pre-release published') + + def publish_release(self): + ''' + Main job to publish the final release. + ''' + # Change release note + releaseNote = ReleaseNote() + note = releaseNote.get_note_body() + title_line = self.template.render('release', { + 'tag': os.environ['CI_COMMIT_TAG'], + 'pipeline': os.environ['CI_PIPELINE_ID'] + }) + releaseNote.send_note(title_line + note) + + # Update Wiki release page + wiki_page = ReleaseWikiPage(self.template) + wiki_page.add_release(os.environ['CI_COMMIT_TAG'], PlaceHolder.clear_all(note)) + wiki_page.save() + + # Keep artifacts + jobs = [] + for artifact in self._get_bin_artifacts(): + if not artifact.job in jobs: + jobs.append(artifact.job) + for job_id in jobs: Job(job_id).keep_artifacts() + + print('Release published') + + def _get_bin_artifacts(self): + ''' + Get the binary artifacts for the current tag. + :return: The list of binary artifacts, based on found descriptions. + :rtype: list of BinArtifact + ''' + DESC_EXT = '.desc' + artifacts = glob.glob('{}*{}'.format(self.release_bin_dir, DESC_EXT)) + artifacts = map(lambda d: BinArtifact(self.release_bin_dir, d, DESC_EXT), artifacts) + artifacts = filter(lambda a: a.tag == os.environ['CI_COMMIT_TAG'], artifacts) + return list(artifacts) diff --git a/.gitlab/releaser/releasewikipage.py b/.gitlab/releaser/releasewikipage.py new file mode 100644 index 0000000000000000000000000000000000000000..c76479610d4eba3ee0244df475f632c9fc9818fd --- /dev/null +++ b/.gitlab/releaser/releasewikipage.py @@ -0,0 +1,59 @@ +import json +import os +import urllib.request + +from placeholder import PlaceHolder +from projectapi import ProjectApi + +class ReleaseWikiPage(ProjectApi): + ''' + Release Wiki page API. + ''' + __PH_TAG = PlaceHolder('tag') + __PH_NOTE = PlaceHolder('note') + __PH_PREVIOUS = PlaceHolder('previous-beg') + + def __init__(self, template): + ''' + :param template: The template to use. + :type template: Template + ''' + if not 'WIKI_RELEASE' in os.environ: + print('CRITICAL WIKI_RELEASE variable is not defined') + exit(1) + ProjectApi.__init__(self, '/wikis/{}'.format(os.environ['WIKI_RELEASE'])) + self.template = template + + # Query existing page + request = self.build_request() + response = urllib.request.urlopen(request) + response_data = response.read().decode() + data = json.loads(response_data) + self.page_content = data['content'] + + def add_release(self, tag, note): + ''' + Add the release to the Wiki page. + ''' + prev_tag = ReleaseWikiPage.__PH_TAG.get_content(self.page_content) + prev_note = ReleaseWikiPage.__PH_NOTE.get_content(self.page_content) + self.page_content = ReleaseWikiPage.__PH_TAG.replace_content(self.page_content, tag) + self.page_content = ReleaseWikiPage.__PH_NOTE.replace_content(self.page_content, note) + previous = self.template.render('previouswiki', { + 'tag': prev_tag, + 'body': prev_note + }) + self.page_content = ReleaseWikiPage.__PH_PREVIOUS.insert_after( + self.page_content, previous) + + def save(self): + send_data = { + 'content': self.page_content, + 'format': 'markdown', + 'slug': os.environ['WIKI_RELEASE'], + 'title': os.environ['WIKI_RELEASE'] + } + send_data_serialized = json.dumps(send_data).encode('utf-8') + request = self.build_request(data=send_data_serialized, method='PUT') + request.add_header('Content-Type', 'application/json') + urllib.request.urlopen(request) diff --git a/.gitlab/releaser/sourceartifact.py b/.gitlab/releaser/sourceartifact.py new file mode 100644 index 0000000000000000000000000000000000000000..b5eda1c81d26cbed6ced8339aff1001bdc562c70 --- /dev/null +++ b/.gitlab/releaser/sourceartifact.py @@ -0,0 +1,23 @@ +import os + +from artifact import Artifact +from fsitemsize import FSItemSize + +class SourceArtifact(Artifact): + ''' + A source artifact. + ''' + + def __init__(self, extention): + ''' + :param extention: The extention of the source archive. + :type extention: str + ''' + Artifact.__init__(self, 'archive.{}'.format(extention), 'Source code ({})'.format(extention), '', '', 'compression') + + def _get_size(self): + return FSItemSize() + + def _build_url(self): + return '{}/repository/{}/{}'.format( + os.environ['CI_PROJECT_URL'], os.environ['CI_COMMIT_TAG'], self.file_name) diff --git a/.gitlab/releaser/template.py b/.gitlab/releaser/template.py new file mode 100644 index 0000000000000000000000000000000000000000..0c607a059dade516d96db0a0a89b8d43b82921e6 --- /dev/null +++ b/.gitlab/releaser/template.py @@ -0,0 +1,31 @@ +import jinja2 +import os + +class Template: + ''' + Manages the template file. The template file is split into blocks. + ''' + def __init__(self, fname): + ''' + :param fname: The name of the template file. + :type fname: str + ''' + path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + environment = jinja2.Environment( + loader=jinja2.FileSystemLoader(path), + trim_blocks=True + ) + self.template = environment.get_template(fname) + + def render(self, block, params): + ''' + Render a block from the template file. + :param block: The name of the block to render. + :param params: The parameters to be used in the block. + :type block: str + :type params: dict + :return: The rendered block. + :rtype: str + ''' + context = self.template.new_context(params) + return jinja2.utils.concat(self.template.blocks[block](context)) diff --git a/Cargo.lock b/Cargo.lock index a1bb5e00f6673d11ae1ad07dc71a151e605919a9..5360a187b3f8bcab195d163ed2192766f3b47c9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,16 +173,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "duniter-blockchain" -version = "0.1.0" -dependencies = [ - "duniter-conf 0.1.0", - "duniter-crypto 0.1.2", - "duniter-dal 0.1.0", - "duniter-documents 0.7.1", - "duniter-message 0.1.0", - "duniter-module 0.1.0", - "duniter-network 0.1.0", - "duniter-wotb 0.8.0-a0.6", +version = "0.1.0-a0.1" +dependencies = [ + "duniter-conf 0.1.0-a0.1", + "duniter-crypto 0.2.0-a0.1", + "duniter-dal 0.1.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-message 0.1.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", + "duniter-wotb 0.8.0-a0.7", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "pbr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -197,10 +197,10 @@ dependencies = [ [[package]] name = "duniter-conf" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-crypto 0.1.2", - "duniter-module 0.1.0", + "duniter-crypto 0.2.0-a0.1", + "duniter-module 0.1.0-a0.1", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", @@ -209,15 +209,15 @@ dependencies = [ [[package]] name = "duniter-core" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "duniter-blockchain 0.1.0", - "duniter-conf 0.1.0", - "duniter-crypto 0.1.2", - "duniter-message 0.1.0", - "duniter-module 0.1.0", - "duniter-network 0.1.0", + "duniter-blockchain 0.1.0-a0.1", + "duniter-conf 0.1.0-a0.1", + "duniter-crypto 0.2.0-a0.1", + "duniter-message 0.1.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -233,7 +233,7 @@ dependencies = [ [[package]] name = "duniter-crypto" -version = "0.1.2" +version = "0.2.0-a0.1" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -244,13 +244,13 @@ dependencies = [ [[package]] name = "duniter-dal" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-crypto 0.1.2", - "duniter-documents 0.7.1", - "duniter-module 0.1.0", - "duniter-network 0.1.0", - "duniter-wotb 0.8.0-a0.6", + "duniter-crypto 0.2.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", + "duniter-wotb 0.8.0-a0.7", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -264,11 +264,11 @@ dependencies = [ [[package]] name = "duniter-documents" -version = "0.7.1" +version = "0.8.0-a0.1" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "duniter-crypto 0.1.2", + "duniter-crypto 0.2.0-a0.1", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -279,23 +279,23 @@ dependencies = [ [[package]] name = "duniter-message" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-crypto 0.1.2", - "duniter-dal 0.1.0", - "duniter-documents 0.7.1", - "duniter-module 0.1.0", - "duniter-network 0.1.0", + "duniter-crypto 0.2.0-a0.1", + "duniter-dal 0.1.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "duniter-module" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-crypto 0.1.2", - "duniter-documents 0.7.1", + "duniter-crypto 0.2.0-a0.1", + "duniter-documents 0.8.0-a0.1", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -303,11 +303,11 @@ dependencies = [ [[package]] name = "duniter-network" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-crypto 0.1.2", - "duniter-documents 0.7.1", - "duniter-module 0.1.0", + "duniter-crypto 0.2.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-module 0.1.0-a0.1", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -318,15 +318,15 @@ dependencies = [ [[package]] name = "duniter-tui" -version = "0.1.0" -dependencies = [ - "duniter-conf 0.1.0", - "duniter-crypto 0.1.2", - "duniter-dal 0.1.0", - "duniter-documents 0.7.1", - "duniter-message 0.1.0", - "duniter-module 0.1.0", - "duniter-network 0.1.0", +version = "0.1.0-a0.1" +dependencies = [ + "duniter-conf 0.1.0-a0.1", + "duniter-crypto 0.2.0-a0.1", + "duniter-dal 0.1.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-message 0.1.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -334,7 +334,7 @@ dependencies = [ [[package]] name = "duniter-wotb" -version = "0.8.0-a0.6" +version = "0.8.0-a0.7" dependencies = [ "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -345,16 +345,16 @@ dependencies = [ [[package]] name = "duniter-ws2p" -version = "0.1.0" -dependencies = [ - "duniter-conf 0.1.0", - "duniter-crypto 0.1.2", - "duniter-dal 0.1.0", - "duniter-documents 0.7.1", - "duniter-message 0.1.0", - "duniter-module 0.1.0", - "duniter-network 0.1.0", - "duniter-wotb 0.8.0-a0.6", +version = "0.1.0-a0.1" +dependencies = [ + "duniter-conf 0.1.0-a0.1", + "duniter-crypto 0.2.0-a0.1", + "duniter-dal 0.1.0-a0.1", + "duniter-documents 0.8.0-a0.1", + "duniter-message 0.1.0-a0.1", + "duniter-module 0.1.0-a0.1", + "duniter-network 0.1.0-a0.1", + "duniter-wotb 0.8.0-a0.7", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -369,11 +369,11 @@ dependencies = [ [[package]] name = "durs" -version = "0.1.0" +version = "0.1.0-a0.1" dependencies = [ - "duniter-core 0.1.0", - "duniter-tui 0.1.0", - "duniter-ws2p 0.1.0", + "duniter-core 0.1.0-a0.1", + "duniter-tui 0.1.0-a0.1", + "duniter-ws2p 0.1.0-a0.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3eecdcaed45e67aa65b3fbca4941d536e73be393..905e909efa42949396f84eee7c127690aefa7dba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "durs" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@duniter.org>","nanocryk <nanocryk@duniter.org>"] description = "DUniter-RS (durs) is a new implementation of Duniter protocol and software in Rust, a safe, concurrent, practical language" license = "AGPL-3.0" diff --git a/blockchain/Cargo.toml b/blockchain/Cargo.toml index 300c2b50e32c01e861215c90fea3a6df9704c88a..59f9cfe500323bf2ca160a2c91404bb8fbdb50ce 100644 --- a/blockchain/Cargo.toml +++ b/blockchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-blockchain" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "Blockchain module for the Duniter project." license = "AGPL-3.0" diff --git a/conf/Cargo.toml b/conf/Cargo.toml index 82d52df89a94b14cd743c98beadc6a07b6993558..9a39060460e515d069c698e5704394c7fdfd8eb8 100644 --- a/conf/Cargo.toml +++ b/conf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-conf" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "Configuration module for the Duniter project." license = "AGPL-3.0" diff --git a/core/Cargo.toml b/core/Cargo.toml index 1cfd1489f5cfb3774b4b2b4f5358c79bf592f58a..7a8e598b9545e3ef86ede1f87ec3adf971a3d3ed 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-core" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "Duniter-rs core." license = "AGPL-3.0" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index c313880c7a23fabbb929516a49ddb08014aba16d..9723b75e99c1233528c30d0f0b6cb7fcb68fdc9c 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-crypto" -version = "0.1.2" +version = "0.2.0-a0.1" authors = ["nanocryk <nanocryk@duniter.org>"] description = "Manage cryptographic building blocks for the Duniter project." repository = "https://git.duniter.org/nodes/rust/duniter-rs" diff --git a/dal/Cargo.toml b/dal/Cargo.toml index 8a80ab5067c7ec193a8f1f441c2efe0515274ae1..a4def26bec0e754802a359f96e4e4b4ffe559630 100644 --- a/dal/Cargo.toml +++ b/dal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-dal" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "Data Access Layer for the Duniter project." license = "AGPL-3.0" diff --git a/documents/Cargo.toml b/documents/Cargo.toml index 539c2476d0091e09bd8fe2770ba95c209f4d49c5..74c7b8d5c0fb6bf919db58a836de0af67a3f5d4d 100644 --- a/documents/Cargo.toml +++ b/documents/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-documents" -version = "0.7.1" +version = "0.8.0-a0.1" authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@ifee.fr>"] description = "Handles Duniter documents" repository = "https://git.duniter.org/nodes/rust/duniter-rs" diff --git a/images/duniter-rs.png b/images/duniter-rs.png new file mode 100644 index 0000000000000000000000000000000000000000..757311a09386b08764b9dda5deba4e0567f0d9ad Binary files /dev/null and b/images/duniter-rs.png differ diff --git a/message/Cargo.toml b/message/Cargo.toml index 86b913c81609e6c2669212a9598aeca390d8025e..59254a6a78df74561cdf930469ea98f03b0e8663 100644 --- a/message/Cargo.toml +++ b/message/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-message" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@duniter.org>"] description = "message model for the Duniter project." license = "AGPL-3.0" diff --git a/module/Cargo.toml b/module/Cargo.toml index cdcc7302e05e6a9eb9e7429aee4aa80a4c6df2f5..9c21549e332254d6aebd5e2b4bb79cbe88b9cb3a 100644 --- a/module/Cargo.toml +++ b/module/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-module" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@duniter.org>"] description = "Modules model for the Duniter project." license = "AGPL-3.0" diff --git a/network/Cargo.toml b/network/Cargo.toml index 91b638382602f067e4efdd106158fe6341727cb1..6ad4c44ab3d34d317938b80fcb7463afeba84fa4 100644 --- a/network/Cargo.toml +++ b/network/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-network" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@duniter.org>"] description = "network model for the Duniter project." license = "AGPL-3.0" diff --git a/network/network_head.rs b/network/network_head.rs index efd2dad5ade55ede0b08e1312223e62741856af9..91bf2843e11cbcffa64cd1232f6b00c40576271a 100644 --- a/network/network_head.rs +++ b/network/network_head.rs @@ -68,9 +68,9 @@ impl NetworkHeadMessageV2 { pub fn to_human_string(&self, max_len: usize, uid: Option<String>) -> String { let short_api = &self.api[4..]; - if max_len > 80 && uid.is_some() { + if max_len > 85 && uid.is_some() { format!( - "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:7} {pre:3} [{api:5}] {mer:02}:{mir:02} {uid}", + "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:14} {pre:3} [{api:5}] {mer:02}:{mir:02} {uid}", node_id = self.node_uuid.to_string(), pubkey = self.pubkey.to_string(), blockstamp = self.blockstamp.to_string(), @@ -82,9 +82,9 @@ impl NetworkHeadMessageV2 { mir = self.free_mirror_room.unwrap_or(0), uid = uid.unwrap(), ) - } else if max_len > 67 { + } else if max_len > 75 { format!( - "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:7} {pre:3} [{api:5}] {mer:02}:{mir:02}", + "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:14} {pre:3} [{api:5}] {mer:02}:{mir:02}", node_id = self.node_uuid.to_string(), pubkey = self.pubkey.to_string(), blockstamp = self.blockstamp.to_string(), @@ -95,9 +95,9 @@ impl NetworkHeadMessageV2 { mer = self.free_member_room.unwrap_or(0), mir = self.free_mirror_room.unwrap_or(0), ) - } else if max_len > 63 { + } else if max_len > 70 { format!( - "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:7} [{api:5}] {mer:02}:{mir:02}", + "{node_id:8}-{pubkey:.8} {blockstamp:.16} {soft:7}:{ver:14} [{api:5}] {mer:02}:{mir:02}", node_id = self.node_uuid.to_string(), pubkey = self.pubkey.to_string(), blockstamp = self.blockstamp.to_string(), diff --git a/release/arch/linux-x64/build-lin-x64.sh b/release/arch/linux-x64/build-lin-x64.sh new file mode 100644 index 0000000000000000000000000000000000000000..d1293e7abee6c158b86230a139def219b668ba0c --- /dev/null +++ b/release/arch/linux-x64/build-lin-x64.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +if [[ -z "${1}" ]]; then + echo "Fatal: no version given to build script" + exit 1 +fi + +# --------- +# Functions +# --------- + +# Create description. +# - +# Parameters: +# 1. Initial file name. +# 2. Building type (either “desktop” or “server”). +# 3. Category (OS, distribution). +create_desc() { + cat >"${1}".desc <<-EOF + { + "version": "${DURS_TAG}", + "job": "${CI_JOB_ID}", + "type": "${2^}", + "category": "${3}", + "arch": "x64" + } + EOF +} + +# Server specific building phase. +# - +# Parameters: +# 1. Building directory. +build_extra_server() { + mkdir -p "${1}/lib/systemd/system" || exit 1 + cp "${ROOT}/release/extra/systemd/durs.service" "${1}/lib/systemd/system" || exit 1 +} + +# Debian package building. +# - +# Parameters: +# 1. Building type (either “desktop” or “server”). +# 2. Debian package name. +build_deb_pack() { + rm -rf "${RELEASES}/durs-x64" + mkdir "${RELEASES}/durs-x64" || exit 1 + cp -r "${ROOT}/release/extra/debian/package/"* "${RELEASES}/durs-x64" || exit 1 + build_extra_${1} "${RELEASES}/durs-x64" + mkdir -p "${RELEASES}/durs-x64/opt/durs/" || exit 1 + chmod 755 "${RELEASES}/durs-x64/DEBIAN/"post* || exit 1 + chmod 755 "${RELEASES}/durs-x64/DEBIAN/"pre* || exit 1 + sed -i "s/Version:.*/Version:${DURS_DEB_VER}/g" "${RELEASES}/durs-x64/DEBIAN/control" || exit 1 + + cd "${RELEASES}/${1}_/" + zip -qr "${RELEASES}/durs-x64/opt/durs/durs.zip" * || exit 1 + + sed -i "s/Package: .*/Package: ${2}/g" "${RELEASES}/durs-x64/DEBIAN/control" || exit 1 + + cd "${RELEASES}" + fakeroot dpkg-deb --build durs-x64 || exit 1 + mv durs-x64.deb "${BIN}/duniter-rust-${1}-${DURS_TAG}-linux-x64.deb" || exit 1 + create_desc "${BIN}/duniter-rust-${1}-${DURS_TAG}-linux-x64.deb" "${1}" "Linux (Ubuntu/Debian)" +} + +# ----------- +# Prepare +# ----------- + +DURS_TAG="v${1}" +DURS_DEB_VER=" ${1}" + +#rustup add target ${TARGET} || exit 1 + +# ----------- +# Folders +# ----------- + +ROOT="${PWD}" +WORK_NAME=work +WORK="${ROOT}/${WORK_NAME}" +DOWNLOADS="${WORK}/downloads" +RELEASES="${WORK}/releases" +BIN="${WORK}/bin" + +mkdir -p "${DOWNLOADS}" "${RELEASES}" "${BIN}" || exit 1 +rm -rf "${BIN}/"*.{deb,tar.gz}{,.desc} # Clean up + +# ----------- +# Downloads +# ----------- + +cd "${DOWNLOADS}" + +# ----------- +# Releases +# ----------- + +# Prepare sources +mkdir -p "${RELEASES}/durs" || exit 1 +cp -r $(find "${ROOT}" -mindepth 1 -maxdepth 1 ! -name "${WORK_NAME}") "${RELEASES}/durs" || exit 1 +cd "${RELEASES}/durs" +rm -Rf .gitignore .git || exit 1 # Remove git files + +# Build binary +echo ">> Building binary..." +cd "${ROOT}" +cargo build --release || exit 1 + +mkdir -p "${RELEASES}/server_" || exit 1 +cp "${ROOT}/target/release/durs" "${RELEASES}/server_/" || exit 1 +#cp "${ROOT}/target/release/durs" "${RELEASES}/desktop_" || exit 1 + +# Copy logo +cp "${ROOT}/images/duniter-rs.png" "${RELEASES}/server_/" || exit 1 +#cp "${ROOT}/images/duniter-rs.png" "${RELEASES}/desktop_" || exit 1 + + +# --------------- +# Build .tar.gz +# --------------- + +cd "${RELEASES}/server_" +tar czf "${BIN}/duniter-rust-server-${DURS_TAG}-linux-x64.tar.gz" * || exit 1 +create_desc "${BIN}/duniter-rust-server-${DURS_TAG}-linux-x64.tar.gz" "Server" "Linux (generic)" + +# ----------------------- +# Build Debian packages +# ----------------------- + +build_deb_pack server durs +#build_deb_pack desktop durs diff --git a/release/extra/debian/package/DEBIAN/control b/release/extra/debian/package/DEBIAN/control new file mode 100644 index 0000000000000000000000000000000000000000..50190018b1689b3ef5155b0c324c93842381fe3b --- /dev/null +++ b/release/extra/debian/package/DEBIAN/control @@ -0,0 +1,9 @@ +Package: duniter-rs +Version: 0.0.1 +Depends: unzip +Section: misc +Priority: optional +Architecture: all +Installed-Size: 20000 +Maintainer: Éloïs <elois@duniter.org> +Description: Crypto-currency software to powering Ğ1 libre currency diff --git a/release/extra/debian/package/DEBIAN/postinst b/release/extra/debian/package/DEBIAN/postinst new file mode 100755 index 0000000000000000000000000000000000000000..13b5d086602e1ef18c4c5768c325c73ea840f7fb --- /dev/null +++ b/release/extra/debian/package/DEBIAN/postinst @@ -0,0 +1,23 @@ +#!/bin/bash + +DURS_ROOT=/opt/durs +DUN_SOURCES=$DURS_ROOT +mkdir -p $DUN_SOURCES + +# Duniter-Rust binary extraction +if [[ -f $DURS_ROOT/durs.zip ]]; then + unzip -q -d $DUN_SOURCES/ $DURS_ROOT/durs.zip + rm -rf $DURS_ROOT/durs.zip +fi + +# Create binary symbolic link +chmod 755 $DUN_SOURCES/bin/durs +ln -s $DUN_SOURCES/durs /usr/bin/durs + +# Add durs user for service +mkdir -p /var/lib/durs +adduser --system --quiet --home /var/lib/durs --no-create-home --disabled-password --group durs +chown durs:durs /var/lib/durs + +# Add reading rights +chmod +r -R $DURS_ROOT diff --git a/release/extra/debian/package/DEBIAN/prerm b/release/extra/debian/package/DEBIAN/prerm new file mode 100755 index 0000000000000000000000000000000000000000..565cc57fc8e8f31cec5a0dd6d173132b37e1414f --- /dev/null +++ b/release/extra/debian/package/DEBIAN/prerm @@ -0,0 +1,5 @@ +#!/bin/bash + +[[ -f /usr/bin/durs ]] && rm /usr/bin/durs +[[ -f /usr/bin/durs-desktop ]] && rm -f /usr/bin/durs-desktop +[[ -d /opt/durs ]] && rm -Rf /opt/durs diff --git a/release/extra/systemd/durs.service b/release/extra/systemd/durs.service new file mode 100644 index 0000000000000000000000000000000000000000..3e8131caafecc9bee6643179c7bfa37aa03b8b03 --- /dev/null +++ b/release/extra/systemd/durs.service @@ -0,0 +1,20 @@ +[Unit] +Description=Duniter-Rust node +After=network.target + +[Service] +Environment="DURS_HOME=/var/lib/durs/.config/durs-dev" +Environment="PROFILE=default" +# If using a key file, DURS_OPTS can be defined like so: +#Environment="DURS_OPTS=--keyfile /etc/durs/keys.yml" +Environment="DURS_OPTS=" +Group=durs +User=durs +Type=forking +ExecStart=/usr/bin/duniter start --home ${DURS_HOME} -p ${PROFILE} $DURS_OPTS +ExecReload=/usr/bin/duniter restart --home ${DURS_HOME} -p ${PROFILE} $DURS_OPTS +ExecStop=/usr/bin/duniter stop --home ${DURS_HOME} -p ${PROFILE} +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 5b3bc0a26cafa512d153ffeb4924df0a87811b42..6db7e07cd0a4c383f029526b996e39f791ab7448 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-tui" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "Terminal user interface for Duniter-Rs." license = "AGPL-3.0" diff --git a/tui/lib.rs b/tui/lib.rs index 3e877a8af94ebd3f586bab9df07b64db81b3466f..022a796f1dd0b13e7ebc1a9c13131b6a086024b0 100644 --- a/tui/lib.rs +++ b/tui/lib.rs @@ -259,7 +259,7 @@ impl TuiModuleDatas { line += 1; write!( stdout, - "{}{}Step NodeId-Pubkey BlockId-BlockHash Soft:Ver Pre [ Api ] MeR:MiR uid", + "{}{}Step NodeId-Pubkey BlockId-BlockHash Soft:Ver Pre [ Api ] MeR:MiR uid", cursor::Goto(1, line), color::Fg(color::White) ).unwrap(); diff --git a/wotb/Cargo.toml b/wotb/Cargo.toml index cabd64653d52a0cdb2d67b4640e0bb228bdeeee7..fe022f517985202212d77a70f8bc9b998c32ac43 100644 --- a/wotb/Cargo.toml +++ b/wotb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-wotb" -version = "0.8.0-a0.6" +version = "0.8.0-a0.7" authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@duniter.org>"] description = "Makes Web of Trust computations for the Duniter project." repository = "https://git.duniter.org/nodes/rust/duniter-rs" diff --git a/ws2p/Cargo.toml b/ws2p/Cargo.toml index 89d3ace4289a8c9dc78deb4d03639a25bb60f26f..e31b8194566eee57aa4bb8b8090e6b83ccd0f661 100644 --- a/ws2p/Cargo.toml +++ b/ws2p/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duniter-ws2p" -version = "0.1.0" +version = "0.1.0-a0.1" authors = ["librelois <elois@ifee.fr>"] description = "WebSocketToPeer API for the Duniter project." license = "AGPL-3.0"