discourse: Add update-plugins action to update.py

(cherry picked from commit 3300282db3f8711a5ed5a5f627c4ddfb83168e3b)
This commit is contained in:
talyz 2021-07-06 18:28:04 +02:00 committed by github-actions[bot]
parent d57e97faef
commit 23cdb918f0
2 changed files with 92 additions and 9 deletions

View File

@ -64,7 +64,6 @@ let
}); });
in in
stdenv.mkDerivation (builtins.removeAttrs args [ "bundlerEnvArgs" ] // { stdenv.mkDerivation (builtins.removeAttrs args [ "bundlerEnvArgs" ] // {
inherit name pname version src meta;
pluginName = if name != null then name else "${pname}-${version}"; pluginName = if name != null then name else "${pname}-${version}";
phases = [ "unpackPhase" "installPhase" ]; phases = [ "unpackPhase" "installPhase" ];
installPhase = '' installPhase = ''

View File

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell #!/usr/bin/env nix-shell
#! nix-shell -i python3 -p bundix bundler nix-update python3 python3Packages.requests python3Packages.click python3Packages.click-log #! nix-shell -i python3 -p bundix bundler nix-update nix-universal-prefetch python3 python3Packages.requests python3Packages.click python3Packages.click-log
import click import click
import click_log import click_log
@ -8,17 +8,22 @@ import tempfile
import re import re
import logging import logging
import subprocess import subprocess
import pathlib import os
import stat
import json
import requests
from distutils.version import LooseVersion from distutils.version import LooseVersion
from pathlib import Path
from typing import Iterable from typing import Iterable
import requests
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class DiscourseRepo: class DiscourseRepo:
version_regex = re.compile(r'^v\d+\.\d+\.\d+$') version_regex = re.compile(r'^v\d+\.\d+\.\d+$')
_latest_commit_sha = None
def __init__(self, owner: str = 'discourse', repo: str = 'discourse'): def __init__(self, owner: str = 'discourse', repo: str = 'discourse'):
self.owner = owner self.owner = owner
self.repo = repo self.repo = repo
@ -35,6 +40,15 @@ class DiscourseRepo:
versions.sort(key=lambda x: LooseVersion(x.replace('v', '')), reverse=True) versions.sort(key=lambda x: LooseVersion(x.replace('v', '')), reverse=True)
return versions return versions
@property
def latest_commit_sha(self) -> str:
if self._latest_commit_sha is None:
r = requests.get(f'https://api.github.com/repos/{self.owner}/{self.repo}/commits?per_page=1')
r.raise_for_status()
self._latest_commit_sha = r.json()[0]['sha']
return self._latest_commit_sha
@staticmethod @staticmethod
def rev2version(tag: str) -> str: def rev2version(tag: str) -> str:
""" """
@ -57,19 +71,23 @@ class DiscourseRepo:
def _call_nix_update(pkg, version): def _call_nix_update(pkg, version):
"""calls nix-update from nixpkgs root dir""" """calls nix-update from nixpkgs root dir"""
nixpkgs_path = pathlib.Path(__file__).parent / '../../../../' nixpkgs_path = Path(__file__).parent / '../../../../'
return subprocess.check_output(['nix-update', pkg, '--version', version], cwd=nixpkgs_path) return subprocess.check_output(['nix-update', pkg, '--version', version], cwd=nixpkgs_path)
def _nix_eval(expr: str):
nixpkgs_path = Path(__file__).parent / '../../../../'
return json.loads(subprocess.check_output(['nix', 'eval', '--json', f'(with import {nixpkgs_path} {{}}; {expr})'], text=True))
def _get_current_package_version(pkg: str): def _get_current_package_version(pkg: str):
nixpkgs_path = pathlib.Path(__file__).parent / '../../../../' return _nix_eval(f'{pkg}.version')
return subprocess.check_output(['nix', 'eval', '--raw', f'nixpkgs.{pkg}.version'], text=True)
def _diff_file(filepath: str, old_version: str, new_version: str): def _diff_file(filepath: str, old_version: str, new_version: str):
repo = DiscourseRepo() repo = DiscourseRepo()
current_dir = pathlib.Path(__file__).parent current_dir = Path(__file__).parent
old = repo.get_file(filepath, 'v' + old_version) old = repo.get_file(filepath, 'v' + old_version)
new = repo.get_file(filepath, 'v' + new_version) new = repo.get_file(filepath, 'v' + new_version)
@ -148,7 +166,7 @@ def update(rev):
version = repo.rev2version(rev) version = repo.rev2version(rev)
logger.debug(f"Using version {version}") logger.debug(f"Using version {version}")
rubyenv_dir = pathlib.Path(__file__).parent / "rubyEnv" rubyenv_dir = Path(__file__).parent / "rubyEnv"
for fn in ['Gemfile.lock', 'Gemfile']: for fn in ['Gemfile.lock', 'Gemfile']:
with open(rubyenv_dir / fn, 'w') as f: with open(rubyenv_dir / fn, 'w') as f:
@ -159,6 +177,72 @@ def update(rev):
_call_nix_update('discourse', repo.rev2version(rev)) _call_nix_update('discourse', repo.rev2version(rev))
@cli.command()
def update_plugins():
"""Update plugins to their latest revision.
"""
plugins = [
{'name': 'discourse-canned-replies'},
{'name': 'discourse-github'},
{'name': 'discourse-math'},
{'name': 'discourse-solved'},
{'name': 'discourse-spoiler-alert'},
{'name': 'discourse-yearly-review'},
]
for plugin in plugins:
fetcher = plugin.get('fetcher') or "fetchFromGitHub"
owner = plugin.get('owner') or "discourse"
name = plugin.get('name')
repo_name = plugin.get('repo_name') or name
repo = DiscourseRepo(owner=owner, repo=repo_name)
prev_commit_sha = _nix_eval(f'discourse.plugins.{name}.src.rev')
if prev_commit_sha == repo.latest_commit_sha:
click.echo(f'Plugin {name} is already at the latest revision')
continue
filename = _nix_eval(f'builtins.unsafeGetAttrPos "src" discourse.plugins.{name}')['file']
prev_hash = _nix_eval(f'discourse.plugins.{name}.src.outputHash')
new_hash = subprocess.check_output([
'nix-universal-prefetch', fetcher,
'--owner', owner,
'--repo', repo_name,
'--rev', repo.latest_commit_sha,
], text=True).strip("\n")
click.echo(f"Update {name}, {prev_commit_sha} -> {repo.latest_commit_sha} in {filename}")
with open(filename, 'r+') as f:
content = f.read()
content = content.replace(prev_commit_sha, repo.latest_commit_sha)
content = content.replace(prev_hash, new_hash)
f.seek(0)
f.write(content)
f.truncate()
rubyenv_dir = Path(filename).parent
gemfile = rubyenv_dir / "Gemfile"
gemfile_text = ''
for line in repo.get_file('plugin.rb', repo.latest_commit_sha).splitlines():
if 'gem ' in line:
gemfile_text = gemfile_text + line + os.linesep
if len(gemfile_text) > 0:
if os.path.isfile(gemfile):
os.remove(gemfile)
subprocess.check_output(['bundle', 'init'], cwd=rubyenv_dir)
os.chmod(gemfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IRGRP | stat.S_IROTH)
with open(gemfile, 'a') as f:
f.write(gemfile_text)
subprocess.check_output(['bundle', 'lock', '--update'], cwd=rubyenv_dir)
subprocess.check_output(['bundix'], cwd=rubyenv_dir)
if __name__ == '__main__': if __name__ == '__main__':
cli() cli()