LUCENE-10365 Wizard changes contributed from Solr (#591)

This commit is contained in:
Jan Høydahl 2022-09-20 12:07:42 +02:00 committed by GitHub
parent 26d6063ec3
commit 00a8112d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 64 deletions

View File

@ -188,6 +188,10 @@ def check_prerequisites(todo=None):
git_ver = run("git --version").splitlines()[0]
except:
sys.exit("You will need git installed")
try:
run("svn --version").splitlines()[0]
except:
sys.exit("You will need svn installed")
if not 'EDITOR' in os.environ:
print("WARNING: Environment variable $EDITOR not set, using %s" % get_editor())
@ -410,7 +414,6 @@ class ReleaseState:
def clear_rc(self):
if ask_yes_no("Are you sure? This will clear and restart RC%s" % self.rc_number):
maybe_remove_rc_from_svn()
dict = {}
for g in list(filter(lambda x: x.in_rc_loop(), self.todo_groups)):
for t in g.get_todos():
t.clear()
@ -418,7 +421,7 @@ class ReleaseState:
try:
shutil.rmtree(self.get_rc_folder())
print("Cleared folder %s" % self.get_rc_folder())
except Exception as e:
except Exception:
print("WARN: Failed to clear %s, please do it manually with higher privileges" % self.get_rc_folder())
self.save()
@ -579,6 +582,7 @@ class ReleaseState:
return "%s.%s.0" % (self.release_version_major, self.release_version_minor + 1)
if self.release_type == 'bugfix':
return "%s.%s.%s" % (self.release_version_major, self.release_version_minor, self.release_version_bugfix + 1)
return None
def get_java_home(self):
return self.get_java_home_for_version(self.release_version)
@ -763,7 +767,6 @@ class Todo(SecretYamlObject):
def display_and_confirm(self):
try:
if self.depends:
ret_str = ""
for dep in ensure_list(self.depends):
g = state.get_group_by_id(dep)
if not g:
@ -1109,21 +1112,23 @@ def configure_pgp(gpg_todo):
if keyid_linenum:
keyid_line = lines[keyid_linenum]
assert keyid_line.startswith('LDAP PGP key: ')
gpg_id = keyid_line[14:].replace(" ", "")[-8:]
gpg_fingerprint = keyid_line[14:].replace(" ", "")
gpg_id = gpg_fingerprint[-8:]
print("Found gpg key id %s on file at Apache (%s)" % (gpg_id, key_url))
else:
print(textwrap.dedent("""\
Could not find your GPG key from Apache servers.
Please make sure you have registered your key ID in
id.apache.org, see links for more info."""))
gpg_id = str(input("Enter your key ID manually, 8 last characters (ENTER=skip): "))
if gpg_id.strip() == '':
gpg_fingerprint = str(input("Enter your key fingerprint manually, all 40 characters (ENTER=skip): "))
if gpg_fingerprint.strip() == '':
return False
elif len(gpg_id) != 8:
print("gpg id must be the last 8 characters of your key id")
gpg_id = gpg_id.upper()
elif len(gpg_fingerprint) != 40:
print("gpg fingerprint must be 40 characters long, do not just input the last 8")
gpg_fingerprint = gpg_fingerprint.upper()
gpg_id = gpg_fingerprint[-8:]
try:
res = run("gpg --list-secret-keys %s" % gpg_id)
res = run("gpg --list-secret-keys %s" % gpg_fingerprint)
print("Found key %s on your private gpg keychain" % gpg_id)
# Check rsa and key length >= 4096
match = re.search(r'^sec +((rsa|dsa)(\d{4})) ', res)
@ -1150,7 +1155,7 @@ def configure_pgp(gpg_todo):
return False
if length < 4096:
print("Your key length is < 4096, Please generate a stronger key.")
print("Alternatively, follow instructions in http://www.apache.org/dev/release-signing.html#note")
print("Alternatively, follow instructions in https://infra.apache.org/release-signing.html#note")
if not ask_yes_no("Have you configured your gpg to avoid SHA-1?"):
print("Please either generate a strong key or reconfigure your client")
return False
@ -1161,7 +1166,7 @@ def configure_pgp(gpg_todo):
need to fix this, then try again"""))
return False
try:
lines = run("gpg --check-signatures %s" % gpg_id).splitlines()
lines = run("gpg --check-signatures %s" % gpg_fingerprint).splitlines()
sigs = 0
apache_sigs = 0
for line in lines:
@ -1173,7 +1178,7 @@ def configure_pgp(gpg_todo):
if apache_sigs < 1:
print(textwrap.dedent("""\
Your key is not signed by any other committer.
Please review http://www.apache.org/dev/openpgp.html#apache-wot
Please review https://infra.apache.org/openpgp.html#apache-wot
and make sure to get your key signed until next time.
You may want to run 'gpg --refresh-keys' to refresh your keychain."""))
uses_apacheid = is_code_signing_key = False
@ -1183,9 +1188,9 @@ def configure_pgp(gpg_todo):
if 'CODE SIGNING KEY' in line.upper():
is_code_signing_key = True
if not uses_apacheid:
print("WARNING: Your key should use your apache-id email address, see http://www.apache.org/dev/release-signing.html#user-id")
print("WARNING: Your key should use your apache-id email address, see https://infra.apache.org/release-signing.html#user-id")
if not is_code_signing_key:
print("WARNING: You code signing key should be labeled 'CODE SIGNING KEY', see http://www.apache.org/dev/release-signing.html#key-comment")
print("WARNING: You code signing key should be labeled 'CODE SIGNING KEY', see https://infra.apache.org/release-signing.html#key-comment")
except Exception as e:
print("Could not check signatures of your key: %s" % e)
@ -1203,6 +1208,23 @@ def configure_pgp(gpg_todo):
gpg_state['apache_id'] = id
gpg_state['gpg_key'] = gpg_id
gpg_state['gpg_fingerprint'] = gpg_fingerprint
print(textwrap.dedent("""\
You can choose between signing the release with the gpg program or with
the gradle signing plugin. Read about the difference by running
./gradlew helpPublishing"""))
gpg_state['use_gradle'] = ask_yes_no("Do you want to sign the release with gradle plugin? No means gpg")
print(textwrap.dedent("""\
You need the passphrase to sign the release.
This script can prompt you securely for your passphrase (will not be stored) and pass it on to
buildAndPushRelease in a secure way. However, you can also configure your passphrase in advance
and avoid having to type it in the terminal. This can be done with either a gpg-agent (for gpg tool)
or in gradle.properties or an ENV.var (for gradle), See ./gradlew helpPublishing for details."""))
gpg_state['prompt_pass'] = ask_yes_no("Do you want this wizard to prompt you for your gpg password? ")
return True
@ -1247,9 +1269,8 @@ class UpdatableSubmenuItem(SubmenuItem):
"""
:ivar ConsoleMenu self.submenu: The submenu to be opened when this item is selected
"""
super(SubmenuItem, self).__init__(text=text, menu=menu, should_exit=should_exit)
super(UpdatableSubmenuItem, self).__init__(text=text, menu=menu, should_exit=should_exit, submenu=submenu)
self.submenu = submenu
if menu:
self.get_submenu().parent = menu
@ -1313,7 +1334,7 @@ class MyScreen(Screen):
class CustomExitItem(ExitItem):
def show(self, index):
return super(ExitItem, self).show(index)
return super(CustomExitItem, self).show(index)
def get_return(self):
return ""
@ -1380,13 +1401,12 @@ def main():
global lucene_news_file
lucene_news_file = os.path.join(state.get_website_git_folder(), 'content', 'core', 'core_news',
"%s-%s-available.md" % (state.get_release_date_iso(), state.release_version.replace(".", "-")))
website_folder = state.get_website_git_folder()
main_menu = UpdatableConsoleMenu(title="Lucene ReleaseWizard",
subtitle=get_releasing_text,
prologue_text="Welcome to the release wizard. From here you can manage the process including creating new RCs. "
"All changes are persisted, so you can exit any time and continue later. Make sure to read the Help section.",
epilogue_text="® 2021 The Lucene project. Licensed under the Apache License 2.0\nScript version v%s)" % getScriptVersion(),
epilogue_text="® 2022 The Lucene project. Licensed under the Apache License 2.0\nScript version v%s)" % getScriptVersion(),
screen=MyScreen())
todo_menu = UpdatableConsoleMenu(title=get_releasing_text,
@ -1533,7 +1553,7 @@ def run_follow(command, cwd=None, fh=sys.stdout, tee=False, live=False, shell=No
lines_written += 1
print_line_cr(line, lines_written, stdout=(fh == sys.stdout), tee=tee)
except Exception as ioe:
except Exception:
pass
if not endstderr:
try:
@ -1554,7 +1574,7 @@ def run_follow(command, cwd=None, fh=sys.stdout, tee=False, live=False, shell=No
errlines.append("%s\n" % line.rstrip())
lines_written += 1
print_line_cr(line, lines_written, stdout=(fh == sys.stdout), tee=tee)
except Exception as e:
except Exception:
pass
if not lines_written > lines_before:
@ -1604,7 +1624,7 @@ class Commands(SecretYamlObject):
fields = loader.construct_mapping(node, deep = True)
return Commands(**fields)
def run(self):
def run(self): # pylint: disable=inconsistent-return-statements # TODO
root = self.get_root_folder()
if self.commands_text:
@ -1623,15 +1643,15 @@ class Commands(SecretYamlObject):
for line in cmd.display_cmd():
print(" %s" % line)
print()
confirm_each = (not self.confirm_each_command is False) and len(commands) > 1
if not self.enable_execute is False:
if self.run_text:
print("\n%s\n" % self.get_run_text())
if len(commands) > 1:
if not self.confirm_each_command is False:
print("You will get prompted before running each individual command.")
else:
print(
"You will not be prompted for each command but will see the ouput of each. If one command fails the execution will stop.")
if confirm_each:
print("You will get prompted before running each individual command.")
else:
print(
"You will not be prompted for each command but will see the output of each. If one command fails the execution will stop.")
success = True
if ask_yes_no("Do you want me to run these commands now?"):
if self.remove_files:
@ -1660,8 +1680,10 @@ class Commands(SecretYamlObject):
folder_prefix = ''
if cmd.cwd:
folder_prefix = cmd.cwd + "_"
if self.confirm_each_command is False or len(commands) == 1 or ask_yes_no("Shall I run '%s' in folder '%s'" % (cmd, cwd)):
if self.confirm_each_command is False:
if confirm_each and cmd.comment:
print("# %s\n" % cmd.get_comment())
if not confirm_each or ask_yes_no("Shall I run '%s' in folder '%s'" % (cmd, cwd)):
if not confirm_each:
print("------------\nRunning '%s' in folder '%s'" % (cmd, cwd))
logfilename = cmd.logfile
logfile = None
@ -1767,6 +1789,8 @@ def abbreviate_homedir(line):
return re.sub(r'([^/]|\b)%s' % os.path.expanduser('~'), "\\1%HOME%", line)
elif 'USERPROFILE' in os.environ:
return re.sub(r'([^/]|\b)%s' % os.path.expanduser('~'), "\\1%USERPROFILE%", line)
else:
return None
else:
return re.sub(r'([^/]|\b)%s' % os.path.expanduser('~'), "\\1~", line)
@ -1847,7 +1871,6 @@ class Command(SecretYamlObject):
def display_cmd(self):
lines = []
pre = post = ''
if self.comment:
if is_windows():
lines.append("REM %s" % self.get_comment())
@ -1893,7 +1916,7 @@ class UserInput(SecretYamlObject):
return result
def create_ical(todo):
def create_ical(todo): # pylint: disable=unused-argument
if ask_yes_no("Do you want to add a Calendar reminder for the close vote time?"):
c = Calendar()
e = Event()
@ -1940,7 +1963,7 @@ def vote_close_72h_holidays():
return holidays if len(holidays) > 0 else None
def prepare_announce_lucene(todo):
def prepare_announce_lucene(todo): # pylint: disable=unused-argument
if not os.path.exists(lucene_news_file):
lucene_text = expand_jinja("(( template=announce_lucene ))")
with open(lucene_news_file, 'w') as fp:
@ -1951,7 +1974,7 @@ def prepare_announce_lucene(todo):
return True
def check_artifacts_available(todo):
def check_artifacts_available(todo): # pylint: disable=unused-argument
try:
cdnUrl = expand_jinja("https://dlcdn.apache.org/lucene/java/{{ release_version }}/lucene-{{ release_version }}-src.tgz.asc")
load(cdnUrl)
@ -1961,7 +1984,7 @@ def check_artifacts_available(todo):
return False
try:
mavenUrl = expand_jinja("https://repo1.maven.org/maven2/org/apache/lucene/lucene-core/{{ release_version }}/lucene-core-{{ release_version }}.pom.asc")
mavenUrl = expand_jinja("https://repo1.maven.org/maven2/org/apache/lucene/lucene-core/{{ release_version }}/lucene-core-{{ release_version }}.jar.asc")
load(mavenUrl)
print("Found %s" % mavenUrl)
except Exception as e:

View File

@ -42,7 +42,7 @@ templates:
As you complete each step the tool will ask you if the task is complete, making
it easy for you to know what is done and what is left to do. If you need to
re-spin a Release Candidata (RC) the Wizard will also help.
re-spin a Release Candidate (RC) the Wizard will also help.
The Lucene project has automated much of the release process with various scripts,
and this wizard is the glue that binds it all together.
@ -132,10 +132,6 @@ templates:
{%- endfor %}
Note: The Apache Software Foundation uses an extensive mirroring network for
distributing releases. It is possible that the mirror you are using may not have
replicated the release yet. If that is the case, please try another mirror.
This also applies to Maven access.
# TODOs belong to groups for easy navigation in menus. Todo objects may contain asciidoc
# descriptions, a number of commands to execute, some links to display, user input to gather
# etc. Here is the documentation of each type of object. For further details, please consult
@ -156,7 +152,7 @@ templates:
# you should introduce the task in more detail. You can use {{ jinja_var }} to
# reference variables. See `releaseWizard.py` for list of global vars supported.
# You can reference state saved from earlier TODO items using syntax
# {{ todi_id.var_name }}
# {{ todo_id.var_name }}
# with `var_name` being either fetched from user_input or persist_vars
# depends: # One or more dependencies which will bar execution
# - todo_id1
@ -217,10 +213,9 @@ groups:
voting rules, create a PGP/GPG key for use with signing and more. Please familiarise
yourself with the resources listed below.
links:
- https://www.apache.org/dev/release-publishing.html
- https://infra.apache.org/release-publishing.html
- https://www.apache.org/legal/release-policy.html
- https://infra.apache.org/release-signing.html
- https://cwiki.apache.org/confluence/display/LUCENE/ReleaseTodo
- !Todo
id: tools
title: Necessary tools are installed
@ -256,12 +251,21 @@ groups:
committer. This makes you a part of the GPG "web of trust" (WoT). Ask a committer
that you know personally to sign your key for you, providing them with the
fingerprint for the key.
You can choose between signing the release with the gpg program or with the
gradle signing plugin. Read about the difference in https://github.com/apache/lucene/blob/main/help/publishing.txt
This wizard can prompt you securely for your passphrase (will not be stored) and pass it on to
buildAndPushRelease in a secure way. However, you can also configure your passphrase in advance
and avoid having to type it in the terminal. This can be done with either a gpg-agent (for gpg tool)
or in `gradle.properties` or an ENV.var (for gradle), See `./gradlew helpPublishing` for details.
function: configure_pgp
links:
- http://www.apache.org/dev/release-signing.html
- http://www.apache.org/dev/openpgp.html#apache-wot
- https://infra.apache.org/release-signing.html
- https://infra.apache.org/openpgp.html#apache-wot
- https://id.apache.org
- https://dist.apache.org/repos/dist/release/lucene/KEYS
- https://github.com/apache/lucene/blob/main/help/publishing.txt
- !TodoGroup
id: preparation
title: Prepare for the release
@ -368,7 +372,7 @@ groups:
cmd: git checkout -b {{ stable_branch }}
tee: true
- !Command
cmd: git push origin {{ stable_branch }}
cmd: git push --set-upstream origin {{ stable_branch }}
tee: true
- !Todo
id: create_minor_branch
@ -397,7 +401,7 @@ groups:
cmd: git checkout -b {{ release_branch }}
tee: true
- !Command
cmd: git push origin {{ release_branch }}
cmd: git push --set-upstream origin {{ release_branch }}
tee: true
- !Todo
id: add_version_major
@ -430,7 +434,7 @@ groups:
There may be other steps needed as well
- !Todo
id: add_version_minor
title: Add a new minor version on stable branch
title: Add a new minor version on stable and unstable branches
types:
- major
- minor
@ -439,7 +443,7 @@ groups:
next_version: "{{ release_version_major }}.{{ release_version_minor + 1 }}.0"
commands: !Commands
root_folder: '{{ git_checkout_folder }}'
commands_text: Run these commands to add the new minor version {{ next_version }} to the stable branch
commands_text: Run these commands to add the new minor version {{ next_version }} to the stable and unstable branches
commands:
- !Command
cmd: git checkout {{ stable_branch }}
@ -451,6 +455,19 @@ groups:
comment: Make sure the edits done by `addVersion.py` are ok, then push
cmd: git add -u . && git commit -m "Add next minor version {{ next_version }}" && git push
logfile: commit-stable.log
- !Command
cmd: git checkout main
tee: true
- !Command
cmd: git pull --ff-only
tee: true
- !Command
cmd: python3 -u dev-tools/scripts/addVersion.py {{ next_version }}
tee: true
- !Command
comment: Make sure the edits done by `addVersion.py` are ok, then push
cmd: git add -u . && git commit -m "Add next minor version {{ next_version }}" && git push
logfile: commit-stable.log
- !Todo
id: sanity_check_doap
title: Sanity check the DOAP files
@ -596,6 +613,14 @@ groups:
- !Command
cmd: git checkout {{ release_branch }}
stdout: true
- !Command
cmd: git clean -df && git checkout -- .
comment: Make sure checkout is clean and up to date
logfile: git_clean.log
tee: true
- !Command
cmd: git pull --ff-only
tee: true
- !Command
cmd: "{{ gradle_cmd }} documentation"
post_description: Check that the task passed. If it failed, commit fixes for the failures before proceeding.
@ -624,7 +649,7 @@ groups:
vars:
logfile: '{{ [rc_folder, ''logs'', ''buildAndPushRelease.log''] | path_join }}'
git_rev: '{{ current_git_rev }}' # Note, git_rev will be recorded in todo state AFTER completion of commands
local_keys: '{% if keys_downloaded %} --local-keys "{{ [config_path, ''KEYS''] | path_join }}"{% endif %}'
local_keys: '{% if keys_downloaded %} --local-keys "{{ [config_path, ''KEYS''] | path_join }}"{% endif %}'
persist_vars:
- git_rev
commands: !Commands
@ -652,8 +677,8 @@ groups:
cmd: git pull --ff-only
tee: true
- !Command
cmd: python3 -u dev-tools/scripts/buildAndPushRelease.py {{ local_keys }} --logfile {{ logfile }} --push-local "{{ dist_file_path }}" --rc-num {{ rc_number }} --sign {{ gpg_key | default("<gpg_key_id>", True) }}
comment: "NOTE: Remember to type your GPG pass-phrase at the prompt!"
cmd: python3 -u dev-tools/scripts/buildAndPushRelease.py {{ local_keys }} --logfile {{ logfile }} --push-local "{{ dist_file_path }}" --rc-num {{ rc_number }} --sign {{ gpg_key | default("<gpg_key_id>", True) }}{% if gpg.use_gradle %} --sign-method-gradle{% endif %}{% if not gpg.prompt_pass %} --gpg-pass-noprompt{% endif %}
comment: "Using {% if gpg.use_gradle %}gradle{% else %}gpg command{% endif %} for signing.{% if gpg.prompt_pass %} Remember to type your GPG pass-phrase at the prompt!{% endif %}"
logfile: build_rc.log
tee: true
- !Todo
@ -683,7 +708,7 @@ groups:
vars:
dist_folder: lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
dist_path: '{{ [dist_file_path, dist_folder] | path_join }}'
dist_url: https://dist.apache.org/repos/dist/dev/lucene/{{ dist_folder}}
dist_url: '{{ dist_url_base }}/{{ dist_folder}}'
commands: !Commands
root_folder: '{{ git_checkout_folder }}'
commands_text: Have your Apache credentials handy, you'll be prompted for your password
@ -701,7 +726,7 @@ groups:
depends: import_svn
vars:
dist_folder: lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
dist_url: https://dist.apache.org/repos/dist/dev/lucene/{{ dist_folder}}
dist_url: '{{ dist_url_base }}/{{ dist_folder}}'
tmp_dir: '{{ [rc_folder, ''smoketest_staged''] | path_join }}'
local_keys: '{% if keys_downloaded %} --local-keys "{{ [config_path, ''KEYS''] | path_join }}"{% endif %}'
commands: !Commands
@ -734,12 +759,12 @@ groups:
Please vote for release candidate {{ rc_number }} for Lucene {{ release_version }}
The artifacts can be downloaded from:
https://dist.apache.org/repos/dist/dev/lucene/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
{{ dist_url_base }}/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
You can run the smoke tester directly with this command:
python3 -u dev-tools/scripts/smokeTestRelease.py \
https://dist.apache.org/repos/dist/dev/lucene/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
{{ dist_url_base }}/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
The vote will be open for at least 72 hours i.e. until {{ vote_close }}.
@ -862,7 +887,7 @@ groups:
vars:
dist_folder: lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
dist_path: '{{ [dist_file_path, dist_folder] | path_join }}'
dist_stage_url: https://dist.apache.org/repos/dist/dev/lucene/{{ dist_folder}}
dist_stage_url: '{{ dist_url_base }}/{{ dist_folder}}'
commands: !Commands
root_folder: '{{ git_checkout_folder }}'
confirm_each_command: false
@ -877,7 +902,7 @@ groups:
title: Move release artifacts to release repo
vars:
dist_folder: lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
dist_stage_url: https://dist.apache.org/repos/dist/dev/lucene/{{ dist_folder}}
dist_stage_url: '{{ dist_url_base }}/{{ dist_folder}}'
dist_release_url: https://dist.apache.org/repos/dist/release/lucene
commands: !Commands
root_folder: '{{ git_checkout_folder }}'
@ -889,7 +914,7 @@ groups:
logfile: svn_mv_lucene.log
tee: true
- !Command
cmd: svn rm -m "Clean up the RC folder for {{ release_version }} RC{{ rc_number }}" https://dist.apache.org/repos/dist/dev/lucene/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
cmd: svn rm -m "Clean up the RC folder for {{ release_version }} RC{{ rc_number }}" {{ dist_url_base }}/lucene-{{ release_version }}-RC{{ rc_number }}-rev-{{ build_rc.git_rev | default("<git_rev>", True) }}
logfile: svn_rm_containing.log
comment: Clean up containing folder on the staging repo
tee: true
@ -937,7 +962,7 @@ groups:
function: check_artifacts_available
description: |
The task will attempt to fetch https://dlcdn.apache.org/lucene/java/{{ release_version }}/lucene-{{ release_version }}-src.tgz.asc
to validate ASF repo, and https://repo1.maven.org/maven2/org/apache/lucene/lucene-core/{{ release_version }}/lucene-core-{{ release_version }}.pom.asc
to validate ASF repo, and https://repo1.maven.org/maven2/org/apache/lucene/lucene-core/{{ release_version }}/lucene-core-{{ release_version }}.jar.asc
to validate Maven repo.
If the check fails, please re-run the task, until it succeeds.
@ -1144,9 +1169,9 @@ groups:
- http://lucene.apache.org/core/api/core/
- !Todo
id: update_doap
title: Update the DOAP files
title: Update the DOAP file
description: |
Update the DOAP RDF files on the unstable, stable and release branches to
Update the Lucene DOAP RDF file on the unstable, stable and release branches to
reflect the new versions (note that the website .htaccess file redirects from their
canonical URLs to their locations in the Lucene Git source repository - see
dev-tools/doap/README.txt for more info)
@ -1549,7 +1574,7 @@ groups:
svnpubsub area `dist/releases/lucene/`. Older releases can be
safely deleted, since they are already backed up in the archives.
Currenlty these versions exist in the distribution directory:
Currently these versions exist in the distribution directory:
*{{ mirrored_versions|join(', ') }}*