mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
More detailed release notes.
Release notes are now broken into sections so that bugs, features, and refactors are clearly delineated. An "Additional Notes" section has been added for changes to documentation and the test suite that do not affect the core code.
This commit is contained in:
parent
0fb8bcbfb7
commit
c8d68bcf2d
@ -6,7 +6,7 @@ pgBackRest aims to be a simple, reliable backup and restore system that can seam
|
||||
|
||||
Instead of relying on traditional backup tools like tar and rsync, pgBackRest implements all backup features internally and uses a custom protocol for communicating with remote systems. Removing reliance on tar and rsync allows for better solutions to database-specific backup challenges. The custom remote protocol allows for more flexibility and limits the types of connections that are required to perform a backup which increases security.
|
||||
|
||||
pgBackRest [v1.01](https://github.com/pgbackrest/pgbackrest/releases/tag/release/1.01) is the current stable release.
|
||||
pgBackRest [v1.01](https://github.com/pgbackrest/pgbackrest/releases/tag/release/1.01) is the current stable release. Release notes are on the [Releases](http://www.pgbackrest.org/release.html) page.
|
||||
|
||||
## Features
|
||||
|
||||
|
@ -631,7 +631,7 @@ sub sectionChildProcess
|
||||
}
|
||||
}
|
||||
# Skip children that have already been processed and error on others
|
||||
elsif ($oChild->nameGet() ne 'title' && $oChild->nameGet() ne 'subtitle' && $oChild->nameGet() ne 'subsubtitle')
|
||||
elsif ($oChild->nameGet() ne 'title')
|
||||
{
|
||||
confess &log(ASSERT, 'unable to process child type ' . $oChild->nameGet());
|
||||
}
|
||||
|
@ -16,7 +16,14 @@ use pgBackRest::Common::Log;
|
||||
use pgBackRest::Common::String;
|
||||
|
||||
use BackRestDoc::Common::DocManifest;
|
||||
use BackRestDoc::Custom::DocCustomRelease;
|
||||
|
||||
####################################################################################################################################
|
||||
# XML tag/param constants
|
||||
####################################################################################################################################
|
||||
use constant XML_SECTION_PARAM_ANCHOR => 'anchor';
|
||||
push @EXPORT, qw(XML_SECTION_PARAM_ANCHOR);
|
||||
use constant XML_SECTION_PARAM_ANCHOR_VALUE_NOINHERIT => 'no-inherit';
|
||||
push @EXPORT, qw(XML_SECTION_PARAM_ANCHOR_VALUE_NOINHERIT);
|
||||
|
||||
####################################################################################################################################
|
||||
# Render tags for various output types
|
||||
@ -180,6 +187,10 @@ sub new
|
||||
{
|
||||
$self->{oReference} =
|
||||
new BackRestDoc::Common::DocConfig(${$self->{oManifest}->sourceGet('reference')}{doc}, $self);
|
||||
|
||||
require BackRestDoc::Custom::DocCustomRelease;
|
||||
BackRestDoc::Custom::DocCustomRelease->import();
|
||||
|
||||
$self->{oRelease} =
|
||||
new BackRestDoc::Custom::DocCustomRelease(${$self->{oManifest}->sourceGet('release')}{doc}, $self);
|
||||
}
|
||||
|
@ -18,6 +18,40 @@ use pgBackRest::Config::Config;
|
||||
use pgBackRest::Config::ConfigHelp;
|
||||
use pgBackRest::FileCommon;
|
||||
|
||||
use BackRestDoc::Common::DocRender;
|
||||
|
||||
####################################################################################################################################
|
||||
# XML node constants
|
||||
####################################################################################################################################
|
||||
use constant XML_PARAM_ID => 'id';
|
||||
|
||||
use constant XML_CONTRIBUTOR_LIST => 'contributor-list';
|
||||
use constant XML_CONTRIBUTOR => 'contributor';
|
||||
use constant XML_CONTRIBUTOR_NAME_DISPLAY => 'contributor-name-display';
|
||||
|
||||
use constant XML_RELEASE_CORE_LIST => 'release-core-list';
|
||||
use constant XML_RELEASE_DOC_LIST => 'release-doc-list';
|
||||
use constant XML_RELEASE_TEST_LIST => 'release-test-list';
|
||||
|
||||
use constant XML_RELEASE_BUG_LIST => 'release-bug-list';
|
||||
use constant XML_RELEASE_FEATURE_LIST => 'release-feature-list';
|
||||
use constant XML_RELEASE_REFACTOR_LIST => 'release-refactor-list';
|
||||
|
||||
use constant XML_RELEASE_ITEM_CONTRIBUTOR_LIST => 'release-item-contributor-list';
|
||||
|
||||
use constant XML_RELEASE_ITEM_CONTRIBUTOR => 'release-item-contributor';
|
||||
use constant XML_RELEASE_ITEM_IDEATOR => 'release-item-ideator';
|
||||
use constant XML_RELEASE_ITEM_REVIEWER => 'release-item-reviewer';
|
||||
|
||||
####################################################################################################################################
|
||||
# Contributor text constants
|
||||
####################################################################################################################################
|
||||
use constant TEXT_CONTRIBUTED => 'Contributed';
|
||||
use constant TEXT_FIXED => 'Fixed';
|
||||
use constant TEXT_FOUND => 'Reported';
|
||||
use constant TEXT_REVIEWED => 'Reviewed';
|
||||
use constant TEXT_SUGGESTED => 'Suggested';
|
||||
|
||||
####################################################################################################################################
|
||||
# CONSTRUCTOR
|
||||
####################################################################################################################################
|
||||
@ -40,6 +74,20 @@ sub new
|
||||
{name => 'oDoc'}
|
||||
);
|
||||
|
||||
# Get contributor list
|
||||
foreach my $oContributor ($self->{oDoc}->nodeGet(XML_CONTRIBUTOR_LIST)->nodeList(XML_CONTRIBUTOR))
|
||||
{
|
||||
my $strContributorId = $oContributor->paramGet(XML_PARAM_ID);
|
||||
|
||||
if (!defined($self->{hContributor}))
|
||||
{
|
||||
$self->{hContributor} = {};
|
||||
$self->{strContributorDefault} = $strContributorId;
|
||||
}
|
||||
|
||||
${$self->{hContributor}}{$strContributorId}{name} = $oContributor->fieldGet(XML_CONTRIBUTOR_NAME_DISPLAY);
|
||||
}
|
||||
|
||||
# Return from function and log return values if any
|
||||
return logDebugReturn
|
||||
(
|
||||
@ -48,6 +96,114 @@ sub new
|
||||
);
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# contributorTextGet
|
||||
#
|
||||
# Get a list of contributors for an item in text format.
|
||||
####################################################################################################################################
|
||||
sub contributorTextGet
|
||||
{
|
||||
my $self = shift;
|
||||
my $oReleaseItem = shift;
|
||||
my $strItemType = shift;
|
||||
|
||||
my $strContributorText;
|
||||
my $hItemContributorType = {};
|
||||
|
||||
# Create a the list of contributors
|
||||
foreach my $strContributorType (XML_RELEASE_ITEM_IDEATOR, XML_RELEASE_ITEM_CONTRIBUTOR, XML_RELEASE_ITEM_REVIEWER)
|
||||
{
|
||||
my $stryItemContributor = [];
|
||||
|
||||
if ($oReleaseItem->nodeTest(XML_RELEASE_ITEM_CONTRIBUTOR_LIST))
|
||||
{
|
||||
foreach my $oContributor ($oReleaseItem->nodeGet(XML_RELEASE_ITEM_CONTRIBUTOR_LIST)->
|
||||
nodeList($strContributorType, false))
|
||||
{
|
||||
push $stryItemContributor, $oContributor->paramGet(XML_PARAM_ID);
|
||||
}
|
||||
}
|
||||
|
||||
if (@$stryItemContributor == 0 && $strContributorType eq XML_RELEASE_ITEM_CONTRIBUTOR)
|
||||
{
|
||||
push $stryItemContributor, $self->{strContributorDefault}
|
||||
}
|
||||
|
||||
$$hItemContributorType{$strContributorType} = $stryItemContributor;
|
||||
}
|
||||
|
||||
# Error if a reviewer is also a contributor
|
||||
foreach my $strReviewer (@{$$hItemContributorType{&XML_RELEASE_ITEM_REVIEWER}})
|
||||
{
|
||||
foreach my $strContributor (@{$$hItemContributorType{&XML_RELEASE_ITEM_CONTRIBUTOR}})
|
||||
{
|
||||
if ($strReviewer eq $strContributor)
|
||||
{
|
||||
confess &log(ERROR, "${strReviewer} cannot be both a contributor and a reviewer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Error if the ideator list is the same as the contributor list
|
||||
if (join(',', @{$$hItemContributorType{&XML_RELEASE_ITEM_IDEATOR}}) eq
|
||||
join(',', @{$$hItemContributorType{&XML_RELEASE_ITEM_CONTRIBUTOR}}))
|
||||
{
|
||||
confess &log(ERROR, 'cannot have same contributor and ideator list: ' .
|
||||
join(', ', @{$$hItemContributorType{&XML_RELEASE_ITEM_CONTRIBUTOR}}));
|
||||
}
|
||||
|
||||
# Remove the default user if they are the only one in a group (to prevent the entire page from being splattered with one name)
|
||||
foreach my $strContributorType (XML_RELEASE_ITEM_IDEATOR, XML_RELEASE_ITEM_CONTRIBUTOR, XML_RELEASE_ITEM_REVIEWER)
|
||||
{
|
||||
if (@{$$hItemContributorType{$strContributorType}} == 1 &&
|
||||
@{$$hItemContributorType{$strContributorType}}[0] eq $self->{strContributorDefault})
|
||||
{
|
||||
$$hItemContributorType{$strContributorType} = [];
|
||||
}
|
||||
}
|
||||
|
||||
# Render the string
|
||||
foreach my $strContributorType (XML_RELEASE_ITEM_CONTRIBUTOR, XML_RELEASE_ITEM_REVIEWER, XML_RELEASE_ITEM_IDEATOR)
|
||||
{
|
||||
my $stryItemContributor = $$hItemContributorType{$strContributorType};
|
||||
my $strContributorTypeText;
|
||||
|
||||
foreach my $strContributor (@{$stryItemContributor})
|
||||
{
|
||||
my $hContributor = ${$self->{hContributor}}{$strContributor};
|
||||
|
||||
if (!defined($hContributor))
|
||||
{
|
||||
confess &log(ERROR, "contributor ${strContributor} does not exist");
|
||||
}
|
||||
|
||||
$strContributorTypeText .= (defined($strContributorTypeText) ? ', ' : '') . $$hContributor{name};
|
||||
}
|
||||
|
||||
if (defined($strContributorTypeText))
|
||||
{
|
||||
$strContributorTypeText = ' by ' . $strContributorTypeText . '.';
|
||||
|
||||
if ($strContributorType eq XML_RELEASE_ITEM_CONTRIBUTOR)
|
||||
{
|
||||
$strContributorTypeText = ($strItemType eq 'bug' ? TEXT_FIXED : TEXT_CONTRIBUTED) . $strContributorTypeText;
|
||||
}
|
||||
elsif ($strContributorType eq XML_RELEASE_ITEM_IDEATOR)
|
||||
{
|
||||
$strContributorTypeText = ($strItemType eq 'bug' ? TEXT_FOUND : TEXT_SUGGESTED) . $strContributorTypeText;
|
||||
}
|
||||
elsif ($strContributorType eq XML_RELEASE_ITEM_REVIEWER)
|
||||
{
|
||||
$strContributorTypeText = TEXT_REVIEWED . $strContributorTypeText;
|
||||
}
|
||||
|
||||
$strContributorText .= (defined($strContributorText) ? ' ' : '') . $strContributorTypeText;
|
||||
}
|
||||
}
|
||||
|
||||
return $strContributorText;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
# docGet
|
||||
#
|
||||
@ -73,14 +229,61 @@ sub docGet
|
||||
$oIntroSectionDoc->textSet($self->{oDoc}->nodeGet('intro')->textGet());
|
||||
|
||||
# Add each release section
|
||||
foreach my $oRelease ($self->{oDoc}->nodeGet('changelog')->nodeList('changelog-release'))
|
||||
my $oSection;
|
||||
my $iDevReleaseTotal = 0;
|
||||
my $iCurrentReleaseTotal = 0;
|
||||
my $iStableReleaseTotal = 0;
|
||||
my $iUnsupportedReleaseTotal = 0;
|
||||
|
||||
foreach my $oRelease ($self->{oDoc}->nodeGet('release-list')->nodeList('release'))
|
||||
{
|
||||
# Get the required release version and date
|
||||
# Get the release version
|
||||
my $strVersion = $oRelease->paramGet('version');
|
||||
|
||||
# Create a release section
|
||||
if ($strVersion =~ /dev$/)
|
||||
{
|
||||
if ($iDevReleaseTotal > 1)
|
||||
{
|
||||
confess &log(ERROR, 'only one development release is allowed');
|
||||
}
|
||||
|
||||
$oSection = $oDoc->nodeAdd('section', undef, {id => 'development'});
|
||||
$oSection->nodeAdd('title')->textSet("Development Notes");
|
||||
|
||||
$iDevReleaseTotal++;
|
||||
}
|
||||
elsif ($iCurrentReleaseTotal == 0)
|
||||
{
|
||||
$oSection = $oDoc->nodeAdd('section', undef, {id => 'current'});
|
||||
$oSection->nodeAdd('title')->textSet("Current Stable Release");
|
||||
$iCurrentReleaseTotal++;
|
||||
}
|
||||
elsif ($strVersion ge '1.00')
|
||||
{
|
||||
if ($iStableReleaseTotal == 0)
|
||||
{
|
||||
$oSection = $oDoc->nodeAdd('section', undef, {id => 'supported'});
|
||||
$oSection->nodeAdd('title')->textSet("Supported Stable Releases");
|
||||
}
|
||||
|
||||
$iStableReleaseTotal++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($iUnsupportedReleaseTotal == 0)
|
||||
{
|
||||
$oSection = $oDoc->nodeAdd('section', undef, {id => 'unsupported'});
|
||||
$oSection->nodeAdd('title')->textSet("Unsupported Releases");
|
||||
}
|
||||
|
||||
$iUnsupportedReleaseTotal++;
|
||||
}
|
||||
|
||||
# Format the date
|
||||
my $strDate = $oRelease->paramGet('date');
|
||||
my $strDateOut = "";
|
||||
|
||||
# Format the date
|
||||
my @stryMonth = ('January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December');
|
||||
|
||||
@ -91,24 +294,95 @@ sub docGet
|
||||
|
||||
if ($strDate =~ /^X/)
|
||||
{
|
||||
$strDateOut .= "\n__No Release Date Set__";
|
||||
$strDateOut .= 'No Release Date Set';
|
||||
}
|
||||
else
|
||||
{
|
||||
$strDateOut .= $stryMonth[(substr($strDate, 5, 2) - 1)] . ' ' .
|
||||
$strDateOut .= 'Released ' . $stryMonth[(substr($strDate, 5, 2) - 1)] . ' ' .
|
||||
(substr($strDate, 8, 2) + 0) . ', ' . substr($strDate, 0, 4);
|
||||
}
|
||||
|
||||
# Add section and titles
|
||||
my $oSection = $oDoc->nodeAdd('section', undef, {id => $strVersion});
|
||||
$oSection->nodeAdd('title')->textSet("$strVersion Release");
|
||||
$oSection->nodeAdd('subtitle')->textSet($oRelease->paramGet('title'));
|
||||
$oSection->nodeAdd('subsubtitle')->textSet('Released ' . $strDateOut);
|
||||
my $oReleaseSection = $oSection->nodeAdd('section', undef, {id => $strVersion});
|
||||
$oReleaseSection->paramSet(XML_SECTION_PARAM_ANCHOR, XML_SECTION_PARAM_ANCHOR_VALUE_NOINHERIT);
|
||||
|
||||
# Add release features
|
||||
foreach my $oReleaseFeature ($oRelease->nodeGet('release-feature-bullet-list')->nodeList('release-feature'))
|
||||
$oReleaseSection->nodeAdd('title')->textSet(
|
||||
"v${strVersion} " . ($strVersion =~ /dev$/ ? '' : 'Release ') . 'Notes');
|
||||
|
||||
$oReleaseSection->nodeAdd('subtitle')->textSet($oRelease->paramGet('title'));
|
||||
$oReleaseSection->nodeAdd('subsubtitle')->textSet($strDateOut);
|
||||
|
||||
# Add release sections
|
||||
my $bAdditionalNotes = false;
|
||||
|
||||
my $hSectionType =
|
||||
{
|
||||
$oSection->nodeAdd('p')->textSet($oReleaseFeature->textGet());
|
||||
&XML_RELEASE_CORE_LIST => {title => 'Core', type => 'core'},
|
||||
&XML_RELEASE_DOC_LIST => {title => 'Documentation', type => 'doc'},
|
||||
&XML_RELEASE_TEST_LIST => {title => 'Test Suite', type => 'test'},
|
||||
};
|
||||
|
||||
foreach my $strSectionType (XML_RELEASE_CORE_LIST, XML_RELEASE_DOC_LIST, XML_RELEASE_TEST_LIST)
|
||||
{
|
||||
if ($oRelease->nodeTest($strSectionType))
|
||||
{
|
||||
# Create subsections for any release section other than core. This breaks up the release items.
|
||||
my $oSubSection = $oReleaseSection;
|
||||
|
||||
if ($strSectionType ne XML_RELEASE_CORE_LIST && !$bAdditionalNotes)
|
||||
{
|
||||
$oReleaseSection->nodeAdd('subtitle')->textSet("Additional Notes");
|
||||
$bAdditionalNotes = true;
|
||||
}
|
||||
|
||||
# Add release note if present
|
||||
if ($oRelease->nodeGet($strSectionType)->nodeTest('p'))
|
||||
{
|
||||
$oSubSection->nodeAdd('p')->textSet($oRelease->nodeGet($strSectionType)->nodeGet('p')->textGet());
|
||||
}
|
||||
|
||||
# Add release item types
|
||||
my $hItemType =
|
||||
{
|
||||
&XML_RELEASE_BUG_LIST => {title => 'Bug Fixes', type => 'bug'},
|
||||
&XML_RELEASE_FEATURE_LIST => {title => 'Features', type=> 'feature'},
|
||||
&XML_RELEASE_REFACTOR_LIST => {title => 'Refactoring', type=> 'refactor'},
|
||||
};
|
||||
|
||||
foreach my $strItemType (XML_RELEASE_BUG_LIST, XML_RELEASE_FEATURE_LIST, XML_RELEASE_REFACTOR_LIST)
|
||||
{
|
||||
if ($oRelease->nodeGet($strSectionType)->nodeTest($strItemType))
|
||||
{
|
||||
my $strTypeText =
|
||||
($strSectionType eq XML_RELEASE_CORE_LIST ? '' : $$hSectionType{$strSectionType}{title}) . ' ' .
|
||||
$$hItemType{$strItemType}{title} . ':';
|
||||
|
||||
$oSubSection->
|
||||
nodeAdd('p')->textSet(
|
||||
{name => 'text', children=> [{name => 'b', value => $strTypeText}]});
|
||||
|
||||
my $oList = $oSubSection->nodeAdd('list');
|
||||
|
||||
# Add release items
|
||||
foreach my $oReleaseFeature ($oRelease->nodeGet($strSectionType)->
|
||||
nodeGet($strItemType)->nodeList('release-item'))
|
||||
{
|
||||
my $oReleaseItemText = $oReleaseFeature->nodeGet('p')->textGet();
|
||||
my $strContributorText = $self->contributorTextGet($oReleaseFeature, $$hItemType{$strItemType}{type});
|
||||
|
||||
if (defined($strContributorText))
|
||||
{
|
||||
push($oReleaseItemText->{oDoc}{children}, ' (');
|
||||
push($oReleaseItemText->{oDoc}{children},
|
||||
{name => 'i', value => $strContributorText});
|
||||
push($oReleaseItemText->{oDoc}{children}, ')');
|
||||
}
|
||||
|
||||
$oList->nodeAdd('list-item')->textSet($oReleaseItemText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ use pgBackRest::Common::String;
|
||||
use pgBackRest::Config::ConfigHelp;
|
||||
|
||||
use BackRestDoc::Common::DocManifest;
|
||||
use BackRestDoc::Common::DocRender;
|
||||
use BackRestDoc::Html::DocHtmlBuilder;
|
||||
use BackRestDoc::Html::DocHtmlElement;
|
||||
|
||||
@ -209,7 +210,10 @@ sub sectionProcess
|
||||
}
|
||||
|
||||
# Working variables
|
||||
$strAnchor = (defined($strAnchor) ? "${strAnchor}/" : '') . $oSection->paramGet('id');
|
||||
$strAnchor =
|
||||
($oSection->paramTest(XML_SECTION_PARAM_ANCHOR, XML_SECTION_PARAM_ANCHOR_VALUE_NOINHERIT) ? '' :
|
||||
(defined($strAnchor) ? "${strAnchor}/" : '')) .
|
||||
$oSection->paramGet('id');
|
||||
|
||||
# Create the section toc element
|
||||
my $oSectionTocElement = new BackRestDoc::Html::DocHtmlElement(HTML_DIV, "section${iDepth}-toc");
|
||||
@ -234,21 +238,6 @@ sub sectionProcess
|
||||
addNew(HTML_A, undef,
|
||||
{strContent => $strSectionTitle, strRef => "#${strAnchor}"});
|
||||
|
||||
# Add subtitle and subsubtitle if they exist
|
||||
if ($oSection->nodeTest('subtitle'))
|
||||
{
|
||||
$oSectionElement->
|
||||
addNew(HTML_DIV, "section${iDepth}-subtitle",
|
||||
{strContent => $self->processText($oSection->nodeGet('subtitle')->textGet())});
|
||||
}
|
||||
|
||||
if ($oSection->nodeTest('subsubtitle'))
|
||||
{
|
||||
$oSectionElement->
|
||||
addNew(HTML_DIV, "section${iDepth}-subsubtitle",
|
||||
{strContent => $self->processText($oSection->nodeGet('subsubtitle')->textGet())});
|
||||
}
|
||||
|
||||
# Add the section intro if it exists
|
||||
if (defined($oSection->textGet(false)))
|
||||
{
|
||||
@ -409,6 +398,20 @@ sub sectionProcess
|
||||
$oList->addNew(HTML_LI, 'list-unordered', {strContent => $self->processText($oListItem->textGet())});
|
||||
}
|
||||
}
|
||||
# Add a subtitle
|
||||
elsif ($oChild->nameGet() eq 'subtitle')
|
||||
{
|
||||
$oSectionBodyElement->
|
||||
addNew(HTML_DIV, "section${iDepth}-subtitle",
|
||||
{strContent => $self->processText($oChild->textGet())});
|
||||
}
|
||||
# Add a subsubtitle
|
||||
elsif ($oChild->nameGet() eq 'subsubtitle')
|
||||
{
|
||||
$oSectionBodyElement->
|
||||
addNew(HTML_DIV, "section${iDepth}-subsubtitle",
|
||||
{strContent => $self->processText($oChild->textGet())});
|
||||
}
|
||||
# Add a subsection
|
||||
elsif ($oChild->nameGet() eq 'section')
|
||||
{
|
||||
|
@ -191,6 +191,7 @@ Section
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 16pt;
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.section1-subsubtitle, .section2-subsubtitle, .section3-subsubtitle
|
||||
@ -200,6 +201,16 @@ Section
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.section1-subtitle
|
||||
{
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
.section1-subsubtitle
|
||||
{
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.section2
|
||||
{
|
||||
margin-top: 1em;
|
||||
@ -212,6 +223,16 @@ Section
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
.section2-subtitle, .section2-subtitle
|
||||
{
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
.section2-subsubtitle, .section3-subsubtitle
|
||||
{
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.section3
|
||||
{
|
||||
margin-left: 1em;
|
||||
|
@ -1,4 +1,5 @@
|
||||
<!ELEMENT doc ((description, intro, changelog)|(config, operation)|(description, variable-list?, cleanup?, section+))>
|
||||
<!ELEMENT doc ((description, intro, contributor-list, release-list)|(config, operation)|
|
||||
(description, variable-list?, cleanup?, section+))>
|
||||
<!ATTLIST doc title CDATA "">
|
||||
<!ATTLIST doc subtitle CDATA "">
|
||||
<!ATTLIST doc toc CDATA "y">
|
||||
@ -117,16 +118,40 @@
|
||||
<!ELEMENT allow (#PCDATA)>
|
||||
<!ELEMENT example (#PCDATA)>
|
||||
|
||||
<!ELEMENT changelog (text?, changelog-release+)>
|
||||
<!ELEMENT contributor-list (contributor+)>
|
||||
|
||||
<!ELEMENT changelog-release (text?, release-feature-bullet-list)>
|
||||
<!ATTLIST changelog-release date CDATA #REQUIRED>
|
||||
<!ATTLIST changelog-release version CDATA #REQUIRED>
|
||||
<!ATTLIST changelog-release title CDATA #REQUIRED>
|
||||
<!ELEMENT contributor (contributor-name-display, contributor-id*)>
|
||||
<!ATTLIST contributor id CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT release-feature-bullet-list (release-feature+)>
|
||||
<!ELEMENT contributor-name-display (#PCDATA)>
|
||||
<!ELEMENT contributor-id (#PCDATA)>
|
||||
<!ATTLIST contributor-id type CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT release-feature (text)>
|
||||
<!ELEMENT release-list (release+)>
|
||||
|
||||
<!ELEMENT release (release-core-list?, release-doc-list?, release-test-list?)>
|
||||
<!ATTLIST release date CDATA #REQUIRED>
|
||||
<!ATTLIST release version CDATA #REQUIRED>
|
||||
<!ATTLIST release title CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT release-core-list (p?, release-bug-list?, release-feature-list?, release-refactor-list?)>
|
||||
<!ELEMENT release-test-list (p?, release-bug-list?, release-feature-list?, release-refactor-list?)>
|
||||
<!ELEMENT release-doc-list (p?, release-bug-list?, release-feature-list?, release-refactor-list?)>
|
||||
|
||||
<!ELEMENT release-bug-list (release-item+)>
|
||||
<!ELEMENT release-feature-list (release-item+)>
|
||||
<!ELEMENT release-refactor-list (release-item+)>
|
||||
|
||||
<!ELEMENT release-item (release-item-contributor-list?, p)*>
|
||||
|
||||
<!ELEMENT release-item-contributor-list (release-item-ideator*, release-item-contributor*, release-item-reviewer*)>
|
||||
|
||||
<!ELEMENT release-item-ideator (#PCDATA)>
|
||||
<!ATTLIST release-item-ideator id CDATA #REQUIRED>
|
||||
<!ELEMENT release-item-contributor (#PCDATA)>
|
||||
<!ATTLIST release-item-contributor id CDATA #REQUIRED>
|
||||
<!ELEMENT release-item-reviewer (#PCDATA)>
|
||||
<!ATTLIST release-item-reviewer id CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT contribute (text)>
|
||||
<!ATTLIST contribute title CDATA #REQUIRED>
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
<p>Instead of relying on traditional backup tools like tar and rsync, <backrest/> implements all backup features internally and uses a custom protocol for communicating with remote systems. Removing reliance on tar and rsync allows for better solutions to database-specific backup challenges. The custom remote protocol allows for more flexibility and limits the types of connections that are required to perform a backup which increases security.</p>
|
||||
|
||||
<p><backrest/> <link url="{[github-url-base]}/releases/tag/release/{[version]}">v{[version]}</link> is the current stable release.</p>
|
||||
<p><backrest/> <link url="{[github-url-base]}/releases/tag/release/{[version]}">v{[version]}</link> is the current stable release. Release notes are on the <link page="{[backrest-page-release]}">Releases</link> page.</p>
|
||||
</section>
|
||||
|
||||
<section id="features">
|
||||
|
1633
doc/xml/release.xml
1633
doc/xml/release.xml
File diff suppressed because it is too large
Load Diff
16
test/test.pl
16
test/test.pl
@ -328,9 +328,21 @@ eval
|
||||
my $strReleaseFile = dirname(dirname($0)) . '/doc/xml/release.xml';
|
||||
my $oReleaseDoc = new BackRestDoc::Common::Doc($strReleaseFile);
|
||||
|
||||
foreach my $oRelease ($oReleaseDoc->nodeGet('changelog')->nodeList('changelog-release'))
|
||||
foreach my $oRelease ($oReleaseDoc->nodeGet('release-list')->nodeList('release'))
|
||||
{
|
||||
if ($oRelease->paramGet('version') ne BACKREST_VERSION)
|
||||
my $strVersion = $oRelease->paramGet('version');
|
||||
|
||||
if ($strVersion =~ /dev$/)
|
||||
{
|
||||
if ($oRelease->nodeTest('release-core-list'))
|
||||
{
|
||||
confess "dev release ${strVersion} must match the program version when core changes have been made";
|
||||
}
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
if ($strVersion ne BACKREST_VERSION)
|
||||
{
|
||||
confess 'unable to find version ' . BACKREST_VERSION . " as the most recent release in ${strReleaseFile}";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user