diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6727f4d23..68cf9e9fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,49 +44,3 @@ variables: MENDER_CLIENT_TAG: description: "Mender Client Docker tag for running integration tests" value: mender-master - -.publish:versions: - stage: publish - image: python:slim - before_script: - - apt-get update && apt-get install -qqy curl hub unzip - - export GITHUB_TOKEN="$GITHUB_BOT_TOKEN_REPO_FULL" - - pip3 install pyyaml - - curl -fsSL https://deno.land/x/install/install.sh | sh - - curl -sLO https://docs.mender.io/releases/versions.json - # Prepare SSH key - - eval $(ssh-agent -s) - - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null - - mkdir -p ~/.ssh - - chmod 700 ~/.ssh - - ssh-keyscan github.com >> ~/.ssh/known_hosts - # Configure git - - git config --global user.email "mender@northern.tech" - - git config --global user.name "Mender Test Bot" - script: - - git for-each-ref --shell --format="tag:%(refname:short) datetime:%(creatordate:format:%s)" "refs/tags/*" | sort -V -r > tags - - python extra/release_info_generator.py - - /root/.deno/bin/deno fmt versions.json - - hub clone mendersoftware/mender-docs-site && mv versions.json mender-docs-site/releases/versions.json && cd mender-docs-site - - git checkout -b update-versions-$(date +%s) - - "git add releases/versions.json && git commit --signoff -m 'chore: Version information update'" - - hub pull-request --push --base mendersoftware:master --message "Version information update" --message "keeping up with the versions" - artifacts: - expire_in: 2w - paths: - - mender-docs-site/releases/versions.json - when: always - -publish:versions:tags: - rules: - - if: $CI_PIPELINE_SOURCE == "schedule" - when: never - - if: $CI_COMMIT_TAG - extends: .publish:versions - -publish:versions:manual: - when: manual - rules: - - if: $CI_PIPELINE_SOURCE == "schedule" - when: never - extends: .publish:versions diff --git a/extra/release_info_generator.py b/extra/release_info_generator.py deleted file mode 100755 index 93744f588..000000000 --- a/extra/release_info_generator.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 Northern.tech AS -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from argparse import Namespace -from calendar import isleap, monthrange -from collections import namedtuple -from contextlib import redirect_stdout -from datetime import datetime, time, timedelta -from io import StringIO -from os import getenv -from re import compile -import json - -from release_tool import do_list_repos - -Tag = namedtuple("Tag", ["version", "datetime"]) -LtsEnd = namedtuple("LtsEnd", ["isExpired", "date"]) - -releaseMatcher = compile(r"([0-9]+)\.([0-9]+)\.([0-9]+)") -tagMatcher = compile(r"tag:'(.*)' datetime:'(\d+)'") - -lastChecked = getenv("LAST_CHECKED", "3.3.0") -endOfToday = datetime.combine(datetime.now(), time.max) - -ltsChecks = { - # until 3.1 all even releases were LTS - "until-3.2": lambda minorVersion, minorValue: minorVersion < "3.2" - and not int(minorValue) % 2, - # from 3.3 all odd releases were assumed to be LTS - "from-3.3": lambda minorVersion, minorValue: minorVersion >= "3.2" - and minorVersion < "3.5" - and int(minorValue) % 2, - # from 3.5 all even releases are assumed to be LTS - "from-3.5": lambda minorVersion, minorValue: minorVersion >= "3.5" - and not int(minorValue) % 2, - # from 3.7 all odd releases are assumed to be LTS - "from-3.7": lambda minorVersion, minorValue: minorVersion >= "3.7" - and int(minorValue) % 2, -} - - -def determine_lts_end(tag, currentMinor, releases): - match = releaseMatcher.match(f"{currentMinor}.0") - if not any( - map(lambda check: check(currentMinor, match.group(2)), ltsChecks.values()) - ): - return - aYear = timedelta( - days=366 - if ( - (tag.datetime.month >= 3 and isleap(tag.datetime.year + 1)) - or (tag.datetime.month < 3 and isleap(tag.datetime.year)) - ) - else 365 - ) - expirationDate = tag.datetime + aYear - if currentMinor in releases: - eolDate = releases[currentMinor]["supported_until"].split("-") - expirationDate = datetime.fromisoformat( - f"{eolDate[0]}-{eolDate[1]}-{monthrange(int(eolDate[0]), int(eolDate[1]))[1]}T{str(time.max)}" - ) - isExpired = expirationDate < endOfToday - return LtsEnd(isExpired, expirationDate) - - -def collect_release_info(tag, minorRelease): - args = { - "list": "git", - "list_format": "json", - "in_integration_version": tag.version, - } - repoList = StringIO() - with redirect_stdout(repoList): - do_list_repos( - Namespace(**args), False, False, False, - ) - - versionReposInfo = json.loads(repoList.getvalue()) - existingInfo = {} - if tag.version in minorRelease: - existingInfo = minorRelease[tag.version] - result = { - "release_date": tag.datetime.strftime("%Y-%m-%d"), - **existingInfo, - **versionReposInfo, - } - result["repos"] = list(filter(lambda repo: (repo["version"]), result["repos"])) - return result - - -def get_releases(): - tags = [] - saasTags = [] - with open("tags", "r") as tagsFile: - for line in tagsFile: - tagMatch = tagMatcher.match(line.strip()) - if not tagMatch: - continue - tag = Tag(tagMatch.group(1), datetime.fromtimestamp(int(tagMatch.group(2)))) - if tag.version.startswith("saas"): - saasTags.append( - {"tag": tag.version, "date": tag.datetime.strftime("%Y-%m-%d")} - ) - match = releaseMatcher.fullmatch(tag.version) - if match and tag.version >= lastChecked: - tags.append(tag) - return {"saasTags": saasTags, "tags": tags} - - -taggedReleases = get_releases() -releases = taggedReleases["tags"] -releaseInformation = {"lts": [], "releases": {}, "saas": taggedReleases["saasTags"]} - -with open("versions.json", "r") as current: - existingReleaseInformation = json.load(current) - releaseInformation["releases"] = existingReleaseInformation["releases"] - -ltsReleases = [] -for release in releases: - print(f"processing {release.version}") - match = releaseMatcher.match(release.version) - currentMinor = f"{match.group(1)}.{match.group(2)}" - initialMinorRelease = next( - (rel for rel in releases if rel.version == f"{currentMinor}.0"), release - ) - ltsEnd = determine_lts_end( - initialMinorRelease, currentMinor, releaseInformation["releases"] - ) - if ltsEnd and not ltsEnd.isExpired and currentMinor not in ltsReleases: - ltsReleases.append(currentMinor) - if currentMinor not in releaseInformation["releases"]: - releaseInformation["releases"][currentMinor] = {} - if ltsEnd: - releaseInformation["releases"][currentMinor][ - "supported_until" - ] = ltsEnd.date.strftime("%Y-%m") - releaseInformation["releases"][currentMinor][ - release.version - ] = collect_release_info(release, releaseInformation["releases"][currentMinor]) - -releaseInformation["releases"] = dict( - sorted(releaseInformation["releases"].items(), reverse=True) -) -releaseInformation["releases"] = { - currentMinor: dict( - sorted(releaseInformation["releases"][currentMinor].items(), reverse=True) - ) - for currentMinor in releaseInformation["releases"].keys() -} - -releaseInformation["lts"] = ltsReleases -with open("versions.json", "w") as result: - json.dump(releaseInformation, result)