mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-08 08:58:00 +00:00
49aa6c2b08
We withdrew our FTP download links in July, when chiark's OS upgrade made its previous ftpd go away. We've had no complaints at all about that, so I think it's time to decide that FTP is officially obsolete, and remove it from the script that does the uploads, and from the release checklist.
224 lines
8.2 KiB
Perl
Executable File
224 lines
8.2 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
# Script to automate some easy-to-mess-up parts of the PuTTY release
|
|
# procedure.
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Getopt::Long;
|
|
use File::Find;
|
|
use File::Temp qw/tempdir/;
|
|
use LWP::UserAgent;
|
|
|
|
my $version = undef;
|
|
my $setver = 0;
|
|
my $upload = 0;
|
|
my $precheck = 0;
|
|
my $postcheck = 0;
|
|
GetOptions("version=s" => \$version,
|
|
"setver" => \$setver,
|
|
"upload" => \$upload,
|
|
"precheck" => \$precheck,
|
|
"postcheck" => \$postcheck)
|
|
or &usage();
|
|
|
|
# --setver: construct a local commit which updates the version
|
|
# number, and the command-line help transcripts in the docs.
|
|
if ($setver) {
|
|
defined $version or die "use --version";
|
|
0 == system "git", "diff-index", "--quiet", "--cached", "HEAD"
|
|
or die "index is dirty";
|
|
0 == system "git", "diff-files", "--quiet" or die "working tree is dirty";
|
|
my $builddir = tempdir(DIR => ".", CLEANUP => 1);
|
|
0 == system "git archive --format=tar HEAD | ( cd $builddir && tar xf - )"
|
|
or die;
|
|
0 == system "cd $builddir && cmake . -DCMAKE_C_FLAGS=-DRELEASE=${version}" or die;
|
|
0 == system "cd $builddir && cmake --build . -t pscp -t plink -j" or die;
|
|
our $pscp_transcript = `cd $builddir && ./pscp --help`;
|
|
$pscp_transcript =~ s/^Unidentified build/Release ${version}/m or die;
|
|
$pscp_transcript =~ s/^/\\c /mg;
|
|
our $plink_transcript = `cd $builddir && ./plink --help`;
|
|
$plink_transcript =~ s/^Unidentified build/Release ${version}/m or die;
|
|
$plink_transcript =~ s/^/\\c /mg;
|
|
&transform("LATEST.VER", sub { s/^\d+\.\d+$/$version/ });
|
|
our $transforming = 0;
|
|
&transform("doc/pscp.but", sub {
|
|
if (/^\\c.*>pscp$/) { $transforming = 1; $_ .= $pscp_transcript; }
|
|
elsif (!/^\\c/) { $transforming = 0; }
|
|
elsif ($transforming) { $_=""; }
|
|
});
|
|
$transforming = 0;
|
|
&transform("doc/plink.but", sub {
|
|
if (/^\\c.*>plink$/) { $transforming = 1; $_ .= $plink_transcript; }
|
|
elsif (!/^\\c/) { $transforming = 0; }
|
|
elsif ($transforming) { $_=""; }
|
|
});
|
|
&transform("Buildscr", sub {
|
|
s!^(set Epoch )\d+!$1 . sprintf "%d", time/86400 - 1000!e });
|
|
0 == system ("git", "commit", "-a", "-m",
|
|
"Update version number for ${version} release.") or die;
|
|
exit 0;
|
|
}
|
|
|
|
# --upload: upload the release to all the places it should live, and
|
|
# check all signatures and md5sums once it arrives there.
|
|
if ($upload) {
|
|
defined $version or die "use --version";
|
|
|
|
# Run this inside the build.out directory.
|
|
-d "maps" or die "no maps directory in cwd";
|
|
-d "putty" or die "no putty directory in cwd";
|
|
|
|
0 == system("rsync", "-av", "maps/",
|
|
"thyestes:src/putty-local/maps-$version")
|
|
or die "could not upload link maps";
|
|
|
|
for my $location (["thyestes", "www/putty/$version"],
|
|
["the", "www/putty/$version"]) {
|
|
my ($host, $path) = @$location;
|
|
0 == system("rsync", "-av", "putty/", "$host:$path")
|
|
or die "could not upload release to $host";
|
|
open my $pipe, "|-", "ssh", $host, "cd $path && sh";
|
|
print $pipe "set -e\n";
|
|
print $pipe "pwd\n";
|
|
find({ wanted => sub
|
|
{
|
|
if (m!^putty/(.*).gpg!) {
|
|
my $file = $1;
|
|
print $pipe "echo verifying $file\n";
|
|
if ($file =~ /sums$/) {
|
|
print $pipe "gpg --verify $file.gpg\n";
|
|
} else {
|
|
print $pipe "gpg --verify $file.gpg $file\n";
|
|
}
|
|
} elsif (m!^putty/(.*sum)s!) {
|
|
print $pipe "echo checking ${1}s\n";
|
|
print $pipe "grep -vF ' (installer version)' ${1}s | grep . | $1 -c\n";
|
|
}
|
|
}, no_chdir => 1}, "putty");
|
|
print $pipe "echo all verified ok\n";
|
|
close $pipe;
|
|
die "VERIFICATION FAILED on $host" if $? != 0;
|
|
}
|
|
|
|
print "Uploaded $version OK!\n";
|
|
exit 0;
|
|
}
|
|
|
|
# --precheck and --postcheck: attempt to download the release from its
|
|
# various locations.
|
|
if ($precheck || $postcheck) {
|
|
defined $version or die "use --version";
|
|
|
|
# Run this inside the build.out directory, so we can check the
|
|
# downloaded files against the exact contents they should have.
|
|
-d "putty" or die "no putty directory in cwd";
|
|
|
|
my $httpprefix = "https://the.earth.li/~sgtatham/putty/";
|
|
|
|
# Go through all the files in build.out.
|
|
find({ wanted => sub
|
|
{
|
|
if (-f $_) {
|
|
die unless (m!^putty/(.*)$!);
|
|
my $path = $1;
|
|
|
|
# Don't try to check .htaccess - web servers will
|
|
# treat it weirdly.
|
|
return if $path =~ m!^(.*/)?.htaccess$!;
|
|
|
|
print "Checking $path\n";
|
|
|
|
my $real_content = "";
|
|
open my $fh, "<", $_ or die "$_: open local file: $!";
|
|
$real_content .= $_ while <$fh>;
|
|
close $fh;
|
|
|
|
my $http_numbered = "${httpprefix}$version/$path";
|
|
my $http_latest = "${httpprefix}latest/$path";
|
|
|
|
my $http_uri;
|
|
|
|
if ($precheck) {
|
|
# Before the 'latest' links/redirects update,
|
|
# we just download from explicitly version-
|
|
# numbered URLs.
|
|
$http_uri = $http_numbered;
|
|
}
|
|
if ($postcheck) {
|
|
# After 'latest' is updated, we're testing that
|
|
# the redirects work, so we download from the
|
|
# URLs with 'latest' in them.
|
|
$http_uri = $http_latest;
|
|
}
|
|
|
|
# Now test-download the files themselves.
|
|
my $ua = LWP::UserAgent->new;
|
|
my $httpresponse = $ua->get($http_uri);
|
|
my $httpdata = $httpresponse->{_content};
|
|
printf " got %d bytes via HTTP", length $httpdata;
|
|
die "HTTP download for $http_uri did not match"
|
|
if $httpdata ne $real_content;
|
|
print ", ok\n";
|
|
|
|
# Check content types on any files likely to go
|
|
# wrong.
|
|
my $ct = $httpresponse->{_headers}->{"content-type"};
|
|
if (defined $ct) {
|
|
printf " got content-type %s", $ct;
|
|
} else {
|
|
printf " got no content-type";
|
|
}
|
|
my $right_ct = undef;
|
|
if ($path =~ m/\.(hlp|cnt|chm)$/) {
|
|
$right_ct = "application/octet-stream";
|
|
} elsif ($path =~ /\.gpg$/) {
|
|
$right_ct = "application/pgp-signature";
|
|
}
|
|
if (defined $right_ct) {
|
|
if ($ct ne $right_ct) {
|
|
die "content-type $ct should be $right_ct";
|
|
} else {
|
|
print ", ok\n";
|
|
}
|
|
} else {
|
|
print "\n";
|
|
}
|
|
|
|
if ($postcheck) {
|
|
# Finally, if we're testing the 'latest' URL,
|
|
# also check that the HTTP redirect header was
|
|
# present and correct.
|
|
my $redirected = $httpresponse->{_request}->{_uri};
|
|
printf " redirect -> %s\n", $redirected;
|
|
die "redirect header wrong for $http_uri"
|
|
if $redirected ne $http_numbered;
|
|
}
|
|
}
|
|
}, no_chdir => 1}, "putty");
|
|
|
|
print "Check OK\n";
|
|
exit 0;
|
|
}
|
|
|
|
&usage();
|
|
|
|
sub transform {
|
|
my ($filename, $proc) = @_;
|
|
my $file;
|
|
open $file, "<", $filename or die "$file: open for read: $!\n";
|
|
my $data = "";
|
|
while (<$file>) {
|
|
$proc->();
|
|
$data .= $_;
|
|
}
|
|
close $file;
|
|
open $file, ">", $filename or die "$file: open for write: $!\n";
|
|
print $file $data;
|
|
close $file or die "$file: close after write: $!\n";;
|
|
}
|
|
|
|
sub usage {
|
|
die "usage: release.pl --set-version=X.YZ\n";
|
|
}
|