From a421e60d0dc04418b1133667536d59a471d0f35b Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Tue, 2 Aug 2022 11:08:23 +0200 Subject: [PATCH] [release] release builder --- dev/build-release.sh | 449 +++++++++++++++++++++++++++++++++ nix/frama-c-checkers-shell.nix | 2 + 2 files changed, 451 insertions(+) create mode 100755 dev/build-release.sh diff --git a/dev/build-release.sh b/dev/build-release.sh new file mode 100755 index 00000000000..e4859e65845 --- /dev/null +++ b/dev/build-release.sh @@ -0,0 +1,449 @@ +#! /usr/bin/env bash +########################################################################## +# # +# This file is part of Frama-C. # +# # +# Copyright (C) 2007-2022 # +# CEA (Commissariat à l'énergie atomique et aux énergies # +# alternatives) # +# # +# you can redistribute it and/or modify it under the terms of the GNU # +# Lesser General Public License as published by the Free Software # +# Foundation, version 2.1. # +# # +# It is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Lesser General Public License for more details. # +# # +# See the GNU Lesser General Public License version 2.1 # +# for more details (enclosed in the file licenses/LGPLv2.1). # +# # +########################################################################## + +# Note: +# +# While this script can be run locally, it is meant to run in the Frama-C CI. +# Thus, it expects to be run from the root of the Frama-C directory and that +# some CI artifacts are available. Namely: +# - 'frama-c.tar.gz' +# - 'api' directory (with api archive inside) +# - 'manuals' directory (with all manuals incl. acsl + version text files) +# Availability of the files is checked when the script starts. The script also +# checks that: +# - the version is stable (VERSION file does not contain '+dev') +# - the commit is tagged with the version (if it contains ~, replaced by -) +# - releases/<VERSION_MAJOR>.<VERSION_MINOR>.md exists +# The script generates the following directories: +# - wiki (for the public Frama-C instance) +# - website +# - opam-repository +# with the correct tree for generated files. + +########################################################################## +# Check binaries + +function echo_red { + echo -e "\e[31m$1\e[0m" +} +function echo_green { + echo -e "\e[32m$1\e[0m" +} + +function show_step { + echo "" + echo "### $1" + echo "" +} + +show_step "Checking binaries availability" + +if ! command -v git-lfs >/dev/null 2>/dev/null; then + echo_red "git-lfs is required" + exit 127 +fi + +# grep needs to be installed +if ! command -v grep --version >/dev/null 2>/dev/null; then + echo_red "grep is required" + exit 127 +fi + +MANUALS_DIR="./manuals" +API_DIR="./api" + +########################################################################## +# Check stable or beta and build names + +show_step "Checking version" + +VERSION="$(cat VERSION)" +VERSION_SAFE="$(echo ${VERSION/~/-})" +VERSION_MODIFIER=$(cat VERSION | sed -e s/[0-9.]*\\\(.*\\\)/\\1/) +VERSION_MAJOR=$(cat VERSION | sed -e s/\\\([0-9]*\\\).[0-9]*.*/\\1/) +VERSION_MINOR=$(cat VERSION | sed -e s/[0-9]*.\\\([0-9]*\\\).*/\\1/) +# TAG="$(git describe --tag)" +CODENAME="$(cat VERSION_CODENAME)" +LOWER_CODENAME="$(echo "$CODENAME" | tr '[:upper:]' '[:lower:]')" +VERSION_AND_CODENAME="${VERSION_SAFE}-${CODENAME}" + +if [ "$VERSION_MODIFIER" == "+dev" ]; then + echo "Development version ($VERSION)" + echo_red "Aborting" + exit 2 +fi + +# if [ "$VERSION_SAFE" != "$TAG" ]; then +# echo "The current commit is not tagged with the current version:" +# echo "Frama-C Version: $VERSION" +# echo "Frama-C Tag : $TAG" +# echo_red "Aborting" +# exit 2 +# fi + +if test -n "$VERSION_MODIFIER"; then + FINAL=no +else + FINAL=yes +fi + +echo "Ready to build release: Frama-C $VERSION - $CODENAME" +echo "MAJOR: $VERSION_MAJOR" +echo "MINOR: $VERSION_MINOR" +echo "FINAL: $FINAL" + +########################################################################## +# Check input files + +function prepare_file { + echo -n "Searching for '$1' ... " + if [ ! -f "$1" ]; then + echo_red "FAILED (aborting)" + exit 2 + fi + echo_green "OK" + chmod 644 $1 +} + +show_step "Searching for a Frama-C source archive" + +TARGZ_BASE="frama-c.tar.gz" +TARGZ_GENERIC="frama-c-source-dist.tar.gz" +TARGZ_VERSION="frama-c-$VERSION_SAFE-$CODENAME.tar.gz" +prepare_file $TARGZ_BASE + +show_step "Searching for a Frama-C API archive" + +TARGZ_API="$API_DIR/frama-c-api.tar.gz" + +prepare_file $TARGZ_API + +show_step "Searching for manuals" + +MANUALS=( + "acsl" + "acsl-implementation" + "aorai-manual" + "e-acsl" + "e-acsl-implementation" + "e-acsl-manual" + "eva-manual" + "metrics-manual" + "plugin-development-guide" + "rte-manual" + "user-manual" + "wp-manual" +) + +COMPANIONS=( + "aorai-example" +) + +for manual in "${MANUALS[@]}"; do + prepare_file "$MANUALS_DIR/$manual.pdf" +done + +for companion in "${COMPANIONS[@]}"; do + prepare_file "$MANUALS_DIR/$companion.tgz" +done + +prepare_file "$MANUALS_DIR/acsl-version.txt" +ACSL_VERSION=$(cat "$MANUALS_DIR/acsl-version.txt") +prepare_file "$MANUALS_DIR/e-acsl-version.txt" +EACSL_VERSION=$(cat "$MANUALS_DIR/e-acsl-version.txt") + +show_step "Searching for changes" + +CHANGES="releases/$VERSION_MAJOR.$VERSION_MINOR.md" +prepare_file $CHANGES + +########################################################################## +# File copy + +function generic_name { + if [ "$1" == "frama-c" ]; then echo "frama-c-source-dist" + elif [ "$1" == "acsl" ]; then echo "acsl" + elif [ "$1" == "e-acsl" ]; then echo "e-acsl" + elif [[ $1 =~ ^e-acsl.*$ ]]; then echo "$1" + else echo "frama-c-$1" + fi +} +function version_name { + if [ "$1" == "acsl" ]; then echo "acsl-$ACSL_VERSION" + elif [ "$1" == "e-acsl" ]; then echo "e-acsl-$EACSL_VERSION" + else echo "$1-$VERSION_AND_CODENAME" + fi +} + +# For the 2 next functions +# $1 : name +# $2 : extension + +function copy_normal { + if [ "yes" == "$GENERIC" ]; then + cp "$MANUALS_DIR/$1.$2" "$MANS_TARGET_DIR/$(generic_name $1).$2" + fi + cp "$MANUALS_DIR/$1.$2" "$MANS_TARGET_DIR/$(version_name $1).$2" +} + +function copy_e_acsl { + if [ "yes" == "$EACSL_SUBDIR" ]; then + EACSL_TARGET_DIR="$MANS_TARGET_DIR/e-acsl" + else + EACSL_TARGET_DIR="$MANS_TARGET_DIR" + fi + if [ "yes" == "$GENERIC" ]; then + cp "$MANUALS_DIR/$1.$2" "$EACSL_TARGET_DIR/$(generic_name $1).$2" + fi + cp "$MANUALS_DIR/$1.$2" "$EACSL_TARGET_DIR/$(version_name $1).$2" +} + +function copy_files { + for manual in "${MANUALS[@]}"; do + if [[ $manual =~ ^e-acsl.*$ ]]; then + copy_e_acsl $manual "pdf" + else + copy_normal $manual "pdf" + fi + done + for companion in "${COMPANIONS[@]}"; do + copy_normal $companion "tgz" + done + + # Eva has an old manual name that might be in use: + if [ "yes" == "$GENERIC" ]; then + cp "$MANS_TARGET_DIR/frama-c-eva-manual.pdf" "$MANS_TARGET_DIR/frama-c-value-analysis.pdf" + fi + + cp $TARGZ_BASE "$GZ_TARGET_DIR/$TARGZ_VERSION" + if [ "yes" == "$GENERIC" ]; then + cp $TARGZ_BASE "$GZ_TARGET_DIR/$TARGZ_GENERIC" + fi + + cp $TARGZ_API "$MANS_TARGET_DIR/frama-c-$VERSION_AND_CODENAME-api.tar.gz" +} + +########################################################################## +# Make opam + +show_step "Building opam repository file" + +OPAM_DIR="opam-repository" +OPAM_FC_DIR="$OPAM_DIR/packages/frama-c/frama-c.$VERSION" + +mkdir -p $OPAM_DIR +mkdir -p $OPAM_FC_DIR + +cat opam/opam | grep -v "^version\:" | grep -v "^name\:" > $OPAM_FC_DIR/opam +cat >>$OPAM_FC_DIR/opam << EOL + +url { + src: "https://git.frama-c.com/pub/frama-c/-/wikis/downloads/$TARGZ_VERSION" + checksum: "sha256=$(sha256sum $TARGZ_BASE | cut -d" " -f1)" +} +EOL + +echo "Opam file built" + +########################################################################## +# Make wiki + +show_step "Building website" + +WIKI_DIR="wiki" +WIKI_DL_DIR="$WIKI_DIR/downloads" +WIKI_MANS_DIR="$WIKI_DIR/manuals" + +mkdir -p $WIKI_DIR +mkdir -p $WIKI_DL_DIR +mkdir -p $WIKI_MANS_DIR + +GZ_TARGET_DIR="$WIKI_DL_DIR" +MANS_TARGET_DIR="$WIKI_MANS_DIR" +EACSL_SUBDIR="no" +GENERIC="no" + +copy_files + +echo "Download directory built" + +WIKI_PAGE="$WIKI_DIR/Frama-C-${VERSION_AND_CODENAME}.md" + +echo "# Frama-C release $VERSION ($CODENAME)" > $WIKI_PAGE +echo "## Sources" >> $WIKI_PAGE +echo "- [$TARGZ_VERSION](downloads/$TARGZ_VERSION)" >> $WIKI_PAGE +echo "" >> $WIKI_PAGE +echo "## Manuals" >> $WIKI_PAGE +for manual in "${MANUALS[@]}"; do + NAME=$(version_name $manual) + echo "- [$manual](manuals/$NAME.pdf)" >> $WIKI_PAGE +done +echo "" >> $WIKI_PAGE +echo "## Main changes" >> $WIKI_PAGE +sed 's/\(\#.*\)/##\1/' $CHANGES >> $WIKI_PAGE + +echo "Wiki page built" + +########################################################################## +# Make website + +show_step "Building website" + +WEBSITE_DIR="./website" +WEBSITE_DL_DIR="$WEBSITE_DIR/download" +WEBSITE_INST_DIR="$WEBSITE_DIR/html/installations" +WEBSITE_EVENTS_DIR="$WEBSITE_DIR/_events" +WEBSITE_VERSIONS_DIR="$WEBSITE_DIR/_fc-versions" + +mkdir -p $WEBSITE_DIR + +# Downloads + +mkdir -p $WEBSITE_DL_DIR +mkdir -p $WEBSITE_DL_DIR/e-acsl + +GZ_TARGET_DIR=$WEBSITE_DL_DIR +MANS_TARGET_DIR=$WEBSITE_DL_DIR +EACSL_SUBDIR="yes" +GENERIC="yes" + +copy_files + +echo "Download directory built" + +# Install + +mkdir -p $WEBSITE_INST_DIR + +INSTALL_WEBPAGE="$WEBSITE_INST_DIR/$LOWER_CODENAME.md" +EXT="$FRAMAC_VERSION_CODENAME (released on $(date +%Y-%m-%d))" + +cat >$INSTALL_WEBPAGE <<EOL +--- +layout: installation_page +version: $LOWER_CODENAME +title: Installation instructions for $CODENAME +--- +EOL +cat ./INSTALL.md | sed -e "s/^\(# Installing Frama-C\)$/\1 $EXT/" >>$INSTALL_WEBPAGE + +echo "Installation file built" + +# Event + +mkdir -p $WEBSITE_EVENTS_DIR + +if [ "$VERSION_MINOR" != 0 ]; then + PREVIOUS="$VERSION_MAJOR.$(($VERSION_MINOR - 1))" +else + PREVIOUS="$(($VERSION_MAJOR - 1)).0" +fi +PREVIOUS_NAME=$(git show $PREVIOUS:VERSION_CODENAME) + +TEXTUAL_VERSION="Frama-C $VERSION ($CODENAME)" +TEXTUAL_PREVIOUS="Frama-C $PREVIOUS ($PREVIOUS_NAME)" + +if [ "$FINAL_RELEASE" = "no" ]; then + EVENT_TITLE="Beta release of $TEXTUAL_VERSION" +else + EVENT_TITLE="Release of $TEXTUAL_VERSION" +fi +VERSION_PAGE="/fc-versions/$LOWER_CODENAME.html" + +EVENT_WEBPAGE="$WEBSITE_EVENTS_DIR/framac-$VERSION_SAFE.md" + +cat >$EVENT_WEBPAGE <<EOL +--- +layout: default +date: $(date +\"%d-%m-%Y\") +short_title: $TEXTUAL_VERSION +title: $EVENT_TITLE +link: /fc-versions/$LOWER_CODENAME.html +--- + +$TEXTUAL_VERSION is out. Download it [here]($VERSION_PAGE). + +Main changes with respect to $TEXTUAL_PREVIOUS include: + +EOL +sed 's/\(\#.*\)/###\1/' $CHANGES >>$EVENT_WEBPAGE + +echo "Event file built" + +# Version + +mkdir -p $WEBSITE_VERSIONS_DIR +VERSION_WEBPAGE="$WEBSITE_DIR/_fc-versions/$LOWER_CODENAME.md" + +if [ "$FINAL_RELEASE" = "no" ]; then + ACSL_OR_BETA="beta: true" +else + ACSL_OR_BETA="acsl: $ACSL_VERSION" +fi + +cat >$VERSION_WEBPAGE <<EOL +--- +layout: version +number: $VERSION_MAJOR +name: $CODENAME +$ACSL_OR_BETA +releases: +- number: $VERSION_MINOR + categories: + - name: Frama-C v$VERSION $CODENAME + files: + - name: Source distribution + link: /download/$TARGZ_VERSION + help: Compilation instructions + help_link: /html/installations/$LOWER_CODENAME.html + - name: User manual + link: /download/user-manual-$VERSION_AND_CODENAME.pdf + - name: Plug-in development guide + link: /download/plugin-development-guide-$VERSION_AND_CODENAME.pdf + help: Hello plug-in tutorial archive + help_link: /download/hello-$VERSION_AND_CODENAME.tar.gz + - name: API Documentation + link: /download/frama-c-$VERSION_AND_CODENAME-api.tar.gz + - name: ACSL $ACSL_VERSION ($CODENAME implementation) + link: /download/acsl-implementation-$VERSION_AND_CODENAME.pdf + - name: Plug-in Manuals + sort: true + files: + - name: Aoraï manual + link: /download/aorai-manual-$VERSION_AND_CODENAME.pdf + help: Aoraï example + help_link: /download/aorai-example-$VERSION_AND_CODENAME.tgz + - name: Metrics manual" + link: /download/metrics-manual-$VERSION_AND_CODENAME.pdf" + - name: Rte manual" + link: /download/rte-manual-$VERSION_AND_CODENAME.pdf" + - name: Eva manual" + link: /download/eva-manual-$VERSION_AND_CODENAME.pdf" + - name: WP manual" + link: /download/wp-manual-$VERSION_AND_CODENAME.pdf" + - name: E-ACSL manual" + link: /download/e-acsl/e-acsl-manual-$VERSION_AND_CODENAME.pdf" +--- +EOL + +echo "Version file built" diff --git a/nix/frama-c-checkers-shell.nix b/nix/frama-c-checkers-shell.nix index 9ccc398534f..de048333505 100644 --- a/nix/frama-c-checkers-shell.nix +++ b/nix/frama-c-checkers-shell.nix @@ -3,6 +3,7 @@ , clang_10 , frama-c-hdrck , git +, git-lfs , gnumake , headache , ocp-indent @@ -13,6 +14,7 @@ stdenv.mkDerivation rec { clang_10 frama-c-hdrck git + git-lfs gnumake headache ocp-indent -- GitLab