Merge branch 'pr-3220' into pmd7-build-scripts-update

This commit is contained in:
Andreas Dangel 2021-04-22 11:35:31 +02:00
commit aea369a80b
44 changed files with 802 additions and 1854 deletions

View File

@ -1,176 +1,87 @@
## PMD CI Scripts
# PMD CI Scripts
This folder contains scripts used for CI.
This folder contains scripts used for CI, that are PMD specific.
It uses the common scripts from [build-tools](https://github.com/pmd/build-tools).
## Secrets
## .ci/files/public-env.gpg
One secret is required for decrypting the GPG Key with which the PMD Releases are signed and
for a ssh key, which is used to copy files to sourceforge.
This files contains the following environment variables:
## Environment variables
* DANGER_GITHUB_API_TOKEN: Token for danger to add comments to PRs as <https://github.com/pmd-test>
* PMD_CI_CHUNK_TOKEN: Token for uploading reports to chunk.io
* PMD_CI_SECRET_PASSPHRASE
* CI_DEPLOY_USER
* CI_DEPLOY_PASSWORD
* CI_SIGN_KEY
* CI_SIGN_PASSPHRASE
* PMD_SF_USER
* PMD_SF_APIKEY
* GITHUB_OAUTH_TOKEN
* GITHUB_BASE_URL
* COVERALLS_REPO_TOKEN
* SONAR_TOKEN
* DANGER_GITHUB_API_TOKEN
* PMD_CI_CHUNK_TOKEN
The file is encrypted, so that the tokens are not automatically disabled when github detects them
in clear text.
## Encrypting
**Decrypting**:
gpg --batch --symmetric --cipher-algo AES256 --passphrase="$PMD_CI_SECRET_PASSPHRASE" file.txt
gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \
--output .ci/files/public-env .ci/files/public-env.gpg
## Known Issues
**Encrypting**:
### Intermittent connection resets or timeouts while downloading dependencies from maven central
gpg --batch --symmetric --cipher-algo AES256 \
--armor --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \
--output .ci/files/public-env.gpg .ci/files/public-env
Root issue seems to be SNAT Configs in Azure, which closes long running [idle TCP connections
after 4 minutes](https://docs.microsoft.com/en-us/azure/load-balancer/troubleshoot-outbound-connection#idletimeout).
## Local tests with docker
The workaround is described in [actions/virtual-environments#1499](https://github.com/actions/virtual-environments/issues/1499)
and [WAGON-545](https://issues.apache.org/jira/browse/WAGON-545)
and [WAGON-486](https://issues.apache.org/jira/browse/WAGON-486):
Using the same docker container as described in [build-env @ build-tools](https://github.com/pmd/build-tools).
The setting `-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3`
makes sure, that Maven doesn't try to use pooled connections that have been unused for more than 180 seconds.
These settings are placed as environment variable `MAVEN_OPTS` in all workflows, so that they are active for
all Maven executions (including builds done by regression tester).
### Testing a push build (snapshot)
Alternatively, pooling could be disabled completely via `-Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false`.
This has the consequence, that for each dependency, that is being downloaded, a new https connection is
established.
Start docker without binding to local directory, so that we can do a fresh checkout
More information about configuring this can be found at [wagon-http](https://maven.apache.org/wagon/wagon-providers/wagon-http/).
$ docker run \
--interactive \
--tty \
--name pmd-build-env_pmd \
pmd-build-env:latest
However, this doesn't work when [dokka-maven-plugin](https://github.com/Kotlin/dokka) is used: This plugin
downloads additional dokka plugins at runtime and reconfigures somehow Maven. After this plugin is loaded,
the above system properties have no effect anymore.
See [dokka/dokka-maven-plugin#1625](https://github.com/Kotlin/dokka/issues/1625) and
[dokka/dokka-maven-plugin#1626](https://github.com/Kotlin/dokka/issues/1626).
The workaround now in place is, to download all the dependencies first, see `inc/maven-dependencies.inc`.
## Hints
### Remote debugging
Debugging remotely is possible with <https://github.com/mxschmitt/action-tmate>.
Just add the following step into the job:
```
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
```
The workflow `troubleshooting` can be started manually, which already contains the tmate action.
**Note**: This is dangerous for push/pull builds on pmd/pmd, because these have access to the secrets and the SSH session
is not protected. Builds triggered by pull requests from forked repositories don't have access to the secrets.
### Local tests with docker
Create a local docker container:
```
cd .ci/docker_ubuntu18.04
docker build -t pmd-ci .
```
This container is based on Ubuntu 18.04, which is used for `ubuntu-latest` github actions runner,
see [Virtual Environment](https://github.com/actions/virtual-environments).
You can run a local instance with docker:
```
docker run -it pmd-ci
```
You'll be dropped into a bash.
#### Testing a push build (snapshot)
Start docker without binding to local directory, so that we can do a fresh checkout: `docker run -it pmd-ci`.
You'll be dropped into a bash. Use the following script, to setup and start the build:
```
MAIN_BRANCH="master"
export MAVEN_OPTS="-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3"
export PMD_CI_JOB_URL="manual job execution in docker"
export PMD_CI_PUSH_COMMIT_COMPARE=""
export PMD_CI_GIT_REF="refs/heads/${MAIN_BRANCH}"
export LANG=en_US.UTF-8
export PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts
export PMD_CI_SECRET_PASSPHRASE="xyz"
export PMD_CI_DEBUG=true
MAIN_BRANCH="master"
eval $(~/create-gh-actions-env.sh push pmd/pmd $MAIN_BRANCH)
cd /workspaces/pmd
rmdir pmd && mkdir pmd
cd pmd
git init
git remote add origin https://github.com/pmd/pmd
git fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +refs/heads/${MAIN_BRANCH}:refs/remotes/origin/${MAIN_BRANCH}
git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/${MAIN_BRANCH}:refs/remotes/origin/${MAIN_BRANCH}
git checkout --progress --force -B ${MAIN_BRANCH} refs/remotes/origin/${MAIN_BRANCH}
.ci/check-environment.sh
f=check-environment.sh; \
mkdir -p .ci && \
( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \
chmod 755 .ci/$f && \
.ci/$f
.ci/build.sh
```
#### Performing a release (push) build
### Testing a pull request
Start docker without binding to local directory, so that we can do a fresh checkout: `docker run -it pmd-ci`.
You'll be dropped into a bash. Use the following script, to setup and start the build:
Same as the above, but this line changes:
```
TAG_NAME="pmd_releases/0.0.0_release_test"
export MAVEN_OPTS="-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3"
export PMD_CI_JOB_URL="manual job execution in docker"
export PMD_CI_PUSH_COMMIT_COMPARE=""
export PMD_CI_GIT_REF="refs/tags/${TAG_NAME}"
export PMD_CI_SECRET_PASSPHRASE="xyz"
cd /workspace/pmd
rmdir pmd && mkdir pmd
cd pmd
git init
git remote add origin https://github.com/pmd/pmd
git fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +refs/tags/${TAG_NAME}:refs/tags/${TAG_NAME}
git checkout --progress --force refs/tags/${TAG_NAME}
.ci/check-environment.sh
.ci/build.sh
eval $(~/create-gh-actions-env.sh pull_request pmd/pmd $MAIN_BRANCH)
```
**Warning:** This will build and upload to maven central!
Maybe update `/workspaces/event.json` to fill in a real pull request number, so that
danger can comment the correct PR.
#### Testing a pull request
Start docker without binding to local directory, so that we can do a fresh checkout: `docker run -it pmd-ci`.
You'll be dropped into a bash. Use the following script, to setup and start the build:
And the checkout must be different. Example for PR 3220:
```
export MAVEN_OPTS="-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3"
export PMD_CI_BRANCH="master" # base branch of the pull request
export PMD_CI_PULL_REQUEST_NUMBER=2913
unset PMD_CI_SECRET_PASSPHRASE
# these are used by danger
export GITHUB_EVENT_PATH=/workspaces/event.json
export GITHUB_REPOSITORY=pmd/pmd
export GITHUB_ACTION=run1
export GITHUB_EVENT_NAME=pull_request
/home/pmd-ci/create-gh-pull-request-event.sh
PMD_CI_PULL_REQUEST_NUMBER=3220
cd /workspace/pmd
rmdir pmd && mkdir pmd
cd pmd
@ -178,8 +89,65 @@ git init
git remote add origin https://github.com/pmd/pmd
git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge:refs/remotes/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge
git checkout --progress --force refs/remotes/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge
.ci/check-environment.sh
.ci/build-pr-win-macos.sh
```
### Forked build
A build executing on a forked repository.
```
$(~/create-gh-actions-env.sh push adangel/pmd $MAIN_BRANCH)
```
### Performing a release (push) build
```
export LANG=en_US.UTF-8
export PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts
export PMD_CI_SECRET_PASSPHRASE="xyz"
export PMD_CI_DEBUG=true
TAG_NAME=pmd_releases/6.33.0
eval $(~/create-gh-actions-env.sh push pmd/pmd refs/tags/$TAG_NAME)
cd /workspaces/pmd
rmdir pmd && mkdir pmd
cd pmd
git init
git remote add origin https://github.com/pmd/pmd
git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/tags/$TAG_NAME:refs/tags/$TAG_NAME
git checkout --progress --force refs/tags/$TAG_NAME
f=check-environment.sh; \
mkdir -p .ci && \
( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \
chmod 755 .ci/$f && \
.ci/$f
#
# .ci/build.sh
#
```
Calling `.ci/build.sh` directly would re-release the tag $TAG_NAME - that's why it is commented out.
All the side-effects of a release would be carried out like creating and publishing a release on github,
uploading the release to sourceforge, uploading the docs to pmd.github.io/docs.pmd-code.org, uploading a
new baseline for the regression tester and so on. While the release should be reproducible and therefore should
produce exactly the same artifacts, re-uploading artifacts is not desired just for testing.
Note that maven-central would not be changed, since this is skipped via MAVEN_OPTS:
`MAVEN_OPTS` contains `-DskipRemoteStaging=true`, so that no maven artifacts are deployed
to maven central (this is set by `create-gh-actions-env.sh`).
So for now in order to test the build script, you need to manually edit the script and comment out the
critical lines... (like publish github releases, uploading files to sourceforge ...). Later a
"dry-run" mode could be added.
Make sure to cleanup after the test, e.g. discard the draft github release.
## Workflow git-repo-sync
Synchronizes the github git repository pmd/pmd on every push to sourceforge.

View File

@ -1,37 +0,0 @@
#!/usr/bin/env bash
source $(dirname $0)/inc/logger.inc
source $(dirname $0)/inc/setup-secrets.inc
source $(dirname $0)/inc/install-openjdk.inc
source $(dirname $0)/inc/maven-dependencies.inc
set -e
log_group_start "Setup private env and OpenJDK"
pmd_ci_setup_private_env
install_openjdk_setdefault 11
export CI_NAME="github actions"
export CI_BUILD_URL="${PMD_CI_JOB_URL}"
export CI_BRANCH="${PMD_CI_GIT_REF##refs/heads/}"
log_group_end
log_group_start "Downloading maven dependencies"
maven_dependencies_resolve
log_group_end
log_group_start "Executing build with coveralls"
./mvnw \
-Dmaven.javadoc.skip=true \
-Dmaven.source.skip \
-Dcheckstyle.skip \
-DrepoToken=${COVERALLS_REPO_TOKEN} \
-B -V -e \
clean package jacoco:report \
coveralls:report -Pcoveralls
if [ $? -ne 0 ]; then
log_error "Error creating coveralls report"
else
log_success "New coveralls result: https://coveralls.io/github/pmd/pmd"
fi
log_group_end

View File

@ -1,39 +0,0 @@
#!/usr/bin/env bash
source $(dirname $0)/inc/logger.inc
source $(dirname $0)/inc/install-openjdk.inc
source $(dirname $0)/inc/regression-tester.inc
source $(dirname $0)/inc/maven-dependencies.inc
set -e
log_group_start "Installing Java"
log_info "Install openjdk11 as default"
install_openjdk_setdefault 11
PMD_EXTRA_OPT=""
if [[ "$(uname)" == Linux* ]]; then
log_info "Install openjdk8 for integration tests and pmd-regression-tests"
install_openjdk 8
PMD_EXTRA_OPT="-Djava8.home=${HOME}/openjdk8"
fi
log_group_end
log_group_start "Downloading maven dependencies"
maven_dependencies_resolve
log_group_end
log_group_start "Building with maven"
./mvnw -e -V -B clean verify ${PMD_EXTRA_OPT}
log_group_end
# Danger is executed only on the linux runner
case "$(uname)" in
Linux*)
log_group_start "Executing danger"
regression_tester_setup_ci
regression_tester_executeDanger
log_group_end
;;
esac

View File

@ -1,33 +0,0 @@
#!/usr/bin/env bash
source $(dirname $0)/inc/logger.inc
source $(dirname $0)/inc/setup-secrets.inc
source $(dirname $0)/inc/install-openjdk.inc
source $(dirname $0)/inc/maven-dependencies.inc
set -e
log_group_start "Setup private env and OpenJDK"
pmd_ci_setup_private_env
install_openjdk_setdefault 11
log_group_end
log_group_start "Downloading maven dependencies"
maven_dependencies_resolve
log_group_end
log_group_start "Executing build with sonar"
./mvnw \
-Dmaven.javadoc.skip=true \
-Dmaven.source.skip \
-Dcheckstyle.skip \
-B -V -e \
clean package \
sonar:sonar -Dsonar.login=${SONAR_TOKEN} -Psonar
if [ $? -ne 0 ]; then
log_error "Error updating sonar..."
else
log_success "New sonar results: https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd"
fi
log_group_end

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +0,0 @@
#!/usr/bin/env bash
#
# This script should check, that all needed commands are available
# and are in the correct version.
#
source $(dirname $0)/inc/logger.inc
set -e
function check() {
local CMD=$1
local VERSION_CMD=$2
local VERSION_STRING=$3
echo -n "Checking ${CMD}..."
if hash "$CMD" 2>/dev/null; then
local VERSION_FULL=$(${VERSION_CMD} 2>&1)
local VERSION=$(echo "${VERSION_FULL}" | grep "${VERSION_STRING}" 2>&1)
if [ -n "${VERSION}" ]; then
echo -e "${COL_GREEN}OK${COL_RESET}"
echo " ${VERSION}"
else
echo -e "${COL_RED}wrong version${COL_RESET}. Expected: ${VERSION_STRING}"
echo " ${VERSION_FULL}"
fi
else
echo -e "${COL_RED}not found!${COL_RESET}"
fi
}
# every OS:
check "curl" "curl --version" "curl"
check "jq" "jq --version" "jq"
case "$(uname)" in
Linux*)
check "ruby" "ruby --version" "ruby 2.7"
check "gpg" "gpg --version" "gpg (GnuPG) 2."
check "printenv" "printenv --version" "printenv (GNU coreutils)"
check "rsync" "rsync --version" "version"
check "ssh" "ssh -V" "OpenSSH"
check "git" "git --version" "git version"
check "mvn" "mvn --version" "Apache Maven"
check "unzip" "unzip --version" "UnZip"
check "zip" "zip --version" "This is Zip"
#check "7z" "7z -version" "7-Zip"
;;
Darwin*)
;;
CYGWIN*|MINGW*)
check "7z" "7z -version" "7-Zip"
;;
*)
log_error "Unknown OS: $(uname)"
exit 1
;;
esac

View File

@ -1,31 +0,0 @@
# https://hub.docker.com/_/ubuntu/
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get upgrade --yes && \
apt-get install --yes curl jq gpg rsync ssh git p7zip-full openjdk-8-jdk \
libgdbm-dev libncurses5-dev automake libtool bison libffi-dev \
sudo nano bash tzdata unzip zip && \
apt-get clean
RUN cd opt && \
curl https://mirror.checkdomain.de/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz | tar xz && \
ln -sf /opt/apache-maven-3.6.3/bin/mvn /usr/local/bin/mvn && \
cd ..
RUN groupadd --gid 1000 pmd-ci && useradd --gid 1000 --uid 1000 --groups sudo \
--shell /bin/bash --create-home --password "" \
pmd-ci
RUN mkdir -p /workspaces/pmd/pmd && chown -R pmd-ci:pmd-ci /workspaces && ln -sf /workspaces /home/pmd-ci/workspaces
USER pmd-ci:pmd-ci
WORKDIR /home/pmd-ci
COPY create-gh-pull-request-event.sh .
COPY install-ruby.sh .
RUN ./install-ruby.sh
CMD ["/bin/bash", "--login"]
#
# build with: docker build -t pmd-ci .
# run with: docker run -it pmd-ci
#

View File

@ -1,10 +0,0 @@
#!/usr/bin/env bash
cat > /workspaces/event.json <<EOF
{
"number": ${PMD_CI_PULL_REQUEST_NUMBER},
"repository": {
"clone_url": "https://github.com/pmd/pmd.git"
}
}
EOF

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL https://get.rvm.io | bash -s stable
source ~/.rvm/scripts/rvm
rvm install 2.7
rvm use 2.7 --default
ruby -v

Binary file not shown.

View File

@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8yHVLHYDsKui8tYg/sFvkDqcs97pEZz0BzK9HtBF4O+/It1drRYRdUAFfjoImfprpKSxkJCTglHixGRp24eNaZ6woWVJ4/bmiMkEqEZAjr1NZ3qw7zIruMJMSkCV+YTtmL4cYcZlvMRPzzOZOnFbV05oi79oy41MUFHYjolK9QxMFNsVNN5iyzFxM3HqSFozz+ylKbFBtDk6ZHZQNRL/Xl2V9DJ69fVzjG4OZfcWNGmmKHHARmsnJyUOMeeKpLjDOe1M6ZdI8HkXWac8yCr9JTETNZZwemZAcS/RKoKCDqfIUOzkZfIPmyaznfVetTGsMi7yQrJhAyjznuNGF4+3lfgTcmRF8wz5FCeUkdYTmy2wNSFi5HiLPfC5OgRtjKzC6yb8rbRjDx6XQ2ph15PKOaXwzk49TaMc0xJvoiGDMZaTU0iTm3Y1/QUtfLvo3/jGMbtUdV3soWpuBAV2JUI4aB5xdLX9iNmcrVzoUe3y9DWuuTX46eoCvpUNXv/DXKhQw1D7xd7J67db5qUck/Akiqi0JR+e0SoBJvZFtYwVNLGC2bIJ/s8SR8X5Zp+1+ypf3WYjIylxQTkO1r4NfI0Cd9qXg7nmUrHAU7Z6xtJmUK8ZWzSST4wul8WkRJURtODLxt5firtlKhyZ93t9Mjuk6mATIPxr/b3x20T+IH463kw== ssh key for pmd. used for travis accessing sourceforge and github.

View File

@ -1,31 +0,0 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<usePluginRegistry/>
<offline/>
<pluginGroups>
<pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
</pluginGroups>
<servers>
<server>
<id>ossrh</id>
<username>${env.CI_DEPLOY_USER}</username>
<password>${env.CI_DEPLOY_PASSWORD}</password>
</server>
</servers>
<mirrors/>
<proxies/>
<profiles>
<profile>
<id>ossrh</id>
<properties>
<gpg.keyname>${env.CI_SIGN_KEY}</gpg.keyname>
<gpg.passphrase>${env.CI_SIGN_PASSPHRASE}</gpg.passphrase>
</properties>
</profile>
</profiles>
<activeProfiles/>
</settings>

Binary file not shown.

Binary file not shown.

44
.ci/git-repo-sync.sh Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Exit this script immediately if a command/function exits with a non-zero status.
set -e
SCRIPT_INCLUDES="log.bash utils.bash setup-secrets.bash"
# shellcheck source=inc/fetch_ci_scripts.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
function git_repo_sync() {
echo
pmd_ci_utils_determine_build_env pmd/pmd
echo
if pmd_ci_utils_is_fork_or_pull_request; then
pmd_ci_log_error "This should not run on forked repositories or pull requests"
exit 0
fi
# only builds on pmd/pmd continue here
pmd_ci_log_group_start "Setup environment"
pmd_ci_setup_secrets_private_env
pmd_ci_setup_secrets_gpg_key
pmd_ci_setup_secrets_ssh
pmd_ci_log_group_end
pmd_ci_log_group_start "Git Sync"
git remote add pmd-sf "${PMD_SF_USER}@git.code.sf.net:/p/pmd/code"
if [ -n "${PMD_CI_BRANCH}" ]; then
git push pmd-sf "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}"
pmd_ci_log_success "Successfully pushed ${PMD_CI_BRANCH} to sourceforge"
elif [ -n "${PMD_CI_TAG}" ]; then
git push pmd-sf tag "${PMD_CI_TAG}"
pmd_ci_log_success "Successfully pushed tag ${PMD_CI_TAG} to sourceforge"
else
pmd_ci_log_error "Don't know what to do: neither PMD_CI_BRANCH nor PMD_CI_TAG is set"
exit 1
fi
pmd_ci_log_group_end
}
git_repo_sync
exit 0

View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
function fetch_ci_scripts() {
local inc_dir
local inc_url
inc_dir="$(dirname "$0")/inc"
inc_url="${PMD_CI_SCRIPTS_URL:-https://raw.githubusercontent.com/pmd/build-tools/master/scripts}/inc"
mkdir -p "${inc_dir}"
for f in ${SCRIPT_INCLUDES}; do
if [ ! -e "${inc_dir}/$f" ]; then
curl -sSL "${inc_url}/$f" > "${inc_dir}/$f"
fi
[ "$PMD_CI_DEBUG" = "true" ] && echo "loading ${inc_dir}/$f in ${MODULE:-$0}"
# shellcheck source=/dev/null
source "${inc_dir}/$f" || exit 1
done
}

View File

@ -1,214 +0,0 @@
#
# The functions here require the following scripts:
# logger.inc
#
# The functions here require the following environment variables:
# GITHUB_OAUTH_TOKEN
# GITHUB_BASE_URL
#
#
# Creates a new release on github with the given tag and target_commit.
# The release is draft and not published.
#
# $RESULT = release json string
#
# See: https://developer.github.com/v3/repos/releases/#create-a-release
#
function gh_releases_createDraftRelease() {
local tagName="$1"
local targetCommitish="$2"
log_debug "$FUNCNAME: Creating new draft release for tag=$tagName and commit=$targetCommitish"
local request=$(cat <<-EOF
{
"tag_name": "${tagName}",
"target_commitish": "${targetCommitish}",
"name": "${tagName}",
"draft": true
}
EOF
)
log_debug "POST $GITHUB_BASE_URL/releases"
log_info "Creating github draft release"
RESULT=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
-H "Content-Type: application/json" \
-X POST \
--data "${request}" \
"$GITHUB_BASE_URL/releases")
log_debug " -> response: $RESULT"
log_success "Created draft release with id $(echo $RESULT | jq --raw-output ".url")"
}
#
# Gets the latest release, if it is a draft and returns with 0.
# Returns with 1, if the latest release is not a draft - meaning, there is no
# draft release (yet?).
#
# RESULT = release json string
#
# See: https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
#
function gh_releases_getLatestDraftRelease() {
log_debug "$FUNCNAME"
log_debug "GET $GITHUB_BASE_URL/releases?per_page=1"
RESULT=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
"$GITHUB_BASE_URL/releases?per_page=1" | jq ".[0]")
log_debug " -> response: $RESULT"
local draft=$(echo $RESULT | jq ".draft")
if [ "$draft" != "true" ]; then
RESULT=""
log_error "Could not find draft release!"
return 1
fi
log_info "Found draft release: $(echo $RESULT | jq --raw-output ".url")"
}
#
# Deletes a release.
#
# See: https://developer.github.com/v3/repos/releases/#delete-a-release
#
function gh_release_deleteRelease() {
local release="$1"
gh_release_getIdFromData "$release"
local releaseId="$RESULT"
log_debug "$FUNCNAME id=$releaseId"
log_debug "DELETE $GITHUB_BASE_URL/releases/$releaseId"
log_info "Deleting github release $releaseId"
local response
response=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
-X DELETE \
"$GITHUB_BASE_URL/releases/$releaseId")
log_debug " -> response: $response"
log_success "Deleted release with id $releaseId"
}
#
# Determines the release id from the given JSON release data.
#
# RESULT = "the release id"
#
function gh_release_getIdFromData() {
local release="$1"
RESULT=$(echo $release | jq --raw-output ".id")
}
#
# Determines the tag_name from the given JSON release data.
#
# RESULT = "the tag name"
#
function gh_release_getTagNameFromData() {
local release="$1"
RESULT=$(echo $release | jq --raw-output ".tag_name")
}
#
# Uploads a asset to an existing release.
#
# See: https://developer.github.com/v3/repos/releases/#upload-a-release-asset
#
function gh_release_uploadAsset() {
local release="$1"
local filename="$2"
local name=$(basename $filename)
gh_release_getIdFromData "$release"
local releaseId="$RESULT"
log_debug "$FUNCNAME: releaseId=$releaseId file=$filename name=$name"
local uploadUrl=$(echo "$release" | jq --raw-output ".upload_url")
uploadUrl="${uploadUrl%%\{\?name,label\}}"
uploadUrl="${uploadUrl}?name=${name}"
log_debug "POST $uploadUrl"
log_info "Uploading $filename to github release $releaseId"
local response
response=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
-H "Content-Type: application/zip" \
--data-binary "@$filename" \
-X POST \
"${uploadUrl}")
log_debug " -> response: $response"
log_success "Uploaded release asset $filename for release $releaseId"
}
#
# Updates the release info: name and body.
# The body is escaped to fit into JSON, so it is allowed for the body to be
# a multi-line string.
#
# See: https://developer.github.com/v3/repos/releases/#edit-a-release
#
function gh_release_updateRelease() {
local release="$1"
local name="$2"
local body="$3"
gh_release_getIdFromData "$release"
local releaseId="$RESULT"
gh_release_getTagNameFromData "$release"
local tagName="$RESULT"
log_debug "$FUNCNAME releaseId=$releaseId name=$name tag_name=$tagName"
body="${body//'\'/\\\\}"
body="${body//$'\r'/}"
body="${body//$'\n'/\\r\\n}"
body="${body//'"'/\\\"}"
local request=$(cat <<-EOF
{
"tag_name": "${tagName}",
"name": "${name}",
"body": "${body}"
}
EOF
)
log_debug "PATCH $GITHUB_BASE_URL/releases/${releaseId}"
log_debug " -> request: $request"
log_info "Updating github release $releaseId"
local response
response=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
-H "Content-Type: application/json" \
--data "${request}" \
-X PATCH \
"$GITHUB_BASE_URL/releases/${releaseId}")
log_debug " -> response: $response"
log_success "Updated release with id=$releaseId"
}
#
# Publish a release by setting draft="false".
# Note: This will send out the notification emails if somebody
# watched the releases.
#
# See: https://developer.github.com/v3/repos/releases/#edit-a-release
#
function gh_release_publishRelease() {
local release="$1"
gh_release_getIdFromData "$release"
local releaseId="$RESULT"
log_debug "$FUNCNAME releaseId=$releaseId"
local request='{"draft":false}'
log_debug "PATCH $GITHUB_BASE_URL/releases/${releaseId}"
log_debug " -> request: $request"
log_info "Publishing github release $releaseId"
local response
response=$(curl --fail -s -H "Authorization: token ${GITHUB_OAUTH_TOKEN}" \
-H "Content-Type: application/json" \
--data "${request}" \
-X PATCH \
"$GITHUB_BASE_URL/releases/${releaseId}")
log_debug " -> response: $response"
local htmlUrl=$(echo "$response" | jq --raw-output ".html_url")
log_success "Published release with id=$releaseId at $htmlUrl"
}

View File

@ -1,80 +0,0 @@
# needs:
# inc/logger
#
# Downloads openjdk from AdoptOpenJDK by accessing the API.
# The API is documented at https://api.adoptopenjdk.net/swagger-ui/
#
function install_openjdk() {
OPENJDK_VERSION=$1
case "$(uname)" in
Linux*)
JDK_OS=linux
COMPONENTS_TO_STRIP=1 # e.g. openjdk-11.0.3+7/bin/java
;;
Darwin*)
JDK_OS=mac
COMPONENTS_TO_STRIP=3 # e.g. jdk-11.0.3+7/Contents/Home/bin/java
;;
CYGWIN*|MINGW*)
JDK_OS=windows
;;
*)
log_error "Unknown OS: $(uname)"
exit 1
;;
esac
DOWNLOAD_URL=$(curl --silent -X GET "https://api.adoptopenjdk.net/v3/assets/feature_releases/${OPENJDK_VERSION}/ga?architecture=x64&heap_size=normal&image_type=jdk&jvm_impl=hotspot&os=${JDK_OS}&page=0&page_size=1&project=jdk&sort_method=DEFAULT&sort_order=DESC&vendor=adoptopenjdk" \
-H "accept: application/json" \
| jq -r ".[0].binaries[0].package.link")
OPENJDK_ARCHIVE=$(basename ${DOWNLOAD_URL})
log_debug "Archive name: ${OPENJDK_ARCHIVE}"
CACHE_DIR=${HOME}/.cache/openjdk
TARGET_DIR=${HOME}/openjdk${OPENJDK_VERSION}
mkdir -p ${CACHE_DIR}
mkdir -p ${TARGET_DIR}
if [ ! -e ${CACHE_DIR}/${OPENJDK_ARCHIVE} ]; then
log_info "Downloading from ${DOWNLOAD_URL} to ${CACHE_DIR}"
curl --location --output ${CACHE_DIR}/${OPENJDK_ARCHIVE} "${DOWNLOAD_URL}"
else
log_info "Skipped download, file ${CACHE_DIR}/${OPENJDK_ARCHIVE} already exists"
fi
log_info "Extracting to ${TARGET_DIR}"
case "$OPENJDK_ARCHIVE" in
*.zip)
7z x ${CACHE_DIR}/${OPENJDK_ARCHIVE} -o${TARGET_DIR}
mv ${TARGET_DIR}/*/* ${TARGET_DIR}/
;;
*.tar.gz)
tar --extract --file ${CACHE_DIR}/${OPENJDK_ARCHIVE} -C ${TARGET_DIR} --strip-components=${COMPONENTS_TO_STRIP}
;;
*)
log_error "Unknown filetype: ${OPENJDK_ARCHIVE}"
exit 1
;;
esac
}
function install_openjdk_setdefault() {
OPENJDK_VERSION=$1
install_openjdk $OPENJDK_VERSION
log_info "Using OpenJDK ${OPENJDK_VERSION} as default"
TARGET_DIR=${HOME}/openjdk${OPENJDK_VERSION}
export JAVA_HOME="${TARGET_DIR}"
export PATH="${TARGET_DIR}/bin:${PATH}"
java -version
}

View File

@ -1,30 +0,0 @@
COL_GREEN="\e[32m"
COL_RED="\e[31m"
COL_RESET="\e[0m"
COL_YELLOW="\e[33;1m"
function log_error() {
echo -e "${COL_RED}[ERROR ] $*${COL_RESET}"
}
function log_info() {
echo -e "${COL_YELLOW}[INFO ] $*${COL_RESET}"
}
function log_success() {
echo -e "${COL_GREEN}[SUCCESS] $*${COL_RESET}"
}
function log_debug() {
true
#echo -e "[DEBUG ] $*"
}
function log_group_start() {
echo "::group::$*"
log_info $*
}
function log_group_end() {
echo "::endgroup::"
}

View File

@ -1,42 +0,0 @@
#
# needs "inc/logger.inc"
#
#
# On azure, outgoing idle connection are dropped after 4 minutes.
# Usually, you can configure wagon with ttl. But these settings are
# ignored, as soon as dokka-maven-plugin is loaded.
# dokka-maven-plugin tries to load additional dependencies at runtime
# and injects a different http client, which is not configured correctly
# and thus maven fails if it tries to download later in the build process
# further dependencies.
#
# The workaround applied here is: first resolve all dependencies,
# then explicitly get dokka-maven-plugin and then resolve all plugins
# execpt for dokka-maven-plugin, as it does not play well with dependency-plugin.
#
function maven_dependencies_resolve() {
dokka_version=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${dokka.version}' \
--non-recursive org.codehaus.mojo:exec-maven-plugin:3.0.0:exec)
# build first the modules, that have dependencies between themselves
# first build pmd-lang-test, pmd-test and pmd-core - used by all modules
./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test -DskipTests -Dpmd.skip=true \
-B -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true
# then build dependencies for pmd-visualforce needs: pmd-apex->pmd-apex-jorje+pmd-test+pmd-core
./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test,pmd-apex-jorje,pmd-apex -DskipTests -Dpmd.skip=true \
-B -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true
# the resolve most other projects. The excluded projects depend on other projects in the reactor, which is not
# completely built yet, so these are excluded.
./mvnw dependency:resolve -pl '!pmd-dist,!pmd-doc,!pmd-scala' -Dsilent -B
./mvnw dependency:get -B -Dsilent \
-DgroupId=org.jetbrains.dokka \
-DartifactId=dokka-maven-plugin \
-Dversion=${dokka_version} \
-Dpackaging=jar \
-DremoteRepositories=jcenter::default::https://jcenter.bintray.com/
./mvnw dependency:resolve-plugins -B -Dsilent -DexcludeGroupIds=org.jetbrains.dokka -Psign
}

View File

@ -1,94 +1,92 @@
#
# The functions here require the following scripts:
# inc/logger.inc
#
#!/usr/bin/env bash
MODULE="pmd-code-api"
SCRIPT_INCLUDES="log.bash"
# shellcheck source=inc/fetch_ci_scripts.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
PMD_CODE_SSH_USER=pmd
PMD_CODE_DOCS_PATH=/docs.pmd-code.org/
function pmd_code_uploadDocumentation() {
local pmdVersion="$1"
local filename="$2"
local basefilename="$(basename $filename)"
local -r pmdVersion="$1"
local -r filename="$2"
local -r basefilename="$(basename "$filename")"
log_debug "$FUNCNAME pmdVersion=$pmdVersion filename=$filename"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion filename=$filename"
scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH}
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH} && \
unzip -qo ${basefilename} && \
rm ${basefilename}"
log_info "Docs updated: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \
unzip -qo \"${basefilename}\" && \
rm \"${basefilename}\""
pmd_ci_log_info "Docs updated: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
}
function pmd_code_removeDocumentation() {
local pmdVersion="$1"
log_debug "$FUNCNAME pmdVersion=$pmdVersion"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion"
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH} && \
rm -rf pmd-doc-${pmdVersion}/"
log_info "Removed docs: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \
rm -rf \"pmd-doc-${pmdVersion}/\""
pmd_ci_log_info "Removed docs: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
}
function pmd_code_createSymlink() {
local pmdVersion="$1"
local name="$2"
local -r pmdVersion="$1"
local -r name="$2"
log_debug "$FUNCNAME pmdVersion=$pmdVersion name=$name"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion name=$name"
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH} && \
rm -f $name && \
ln -s pmd-doc-${pmdVersion} $name"
log_info "Symlink created: https://docs.pmd-code.org/$name/ -> https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \
rm -f \"$name\" && \
ln -s \"pmd-doc-${pmdVersion}\" \"$name\""
pmd_ci_log_info "Symlink created: https://docs.pmd-code.org/$name/ -> https://docs.pmd-code.org/pmd-doc-${pmdVersion}/"
}
function pmd_code_uploadJavadoc() {
local pmdVersion="$1"
local basePath="$2"
local -r pmdVersion="$1"
local -r basePath="$2"
log_debug "$FUNCNAME pmdVersion=$pmdVersion basePath=$basePath"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion basePath=$basePath"
for i in ${basePath}/*/target/*-javadoc.jar */*/target/*-javadoc.jar; do
for i in "${basePath}"/*/target/*-javadoc.jar */*/target/*-javadoc.jar; do
pmd_code_uploadJavadocModule "$pmdVersion" "$i"
done
pmd_code_fixPmdLangTestStyle "${basePath}"
# make sure https://docs.pmd-code.org/apidocs/ shows directory index
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH}/apidocs && \
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \
echo 'Options +Indexes' > .htaccess"
log_info "Directory index enabled for https://docs.pmd-code.org/apidocs/"
pmd_ci_log_info "Directory index enabled for https://docs.pmd-code.org/apidocs/"
}
function pmd_code_uploadJavadocModule() {
local pmdVersion="$1"
local moduleJavadocJar="$2"
local moduleJavadocJarBasename="$(basename $moduleJavadocJar)"
local module=${moduleJavadocJarBasename%%-${pmdVersion}-javadoc.jar}
local -r pmdVersion="$1"
local -r moduleJavadocJar="$2"
local -r moduleJavadocJarBasename="$(basename "$moduleJavadocJar")"
local -r module=${moduleJavadocJarBasename%%-${pmdVersion}-javadoc.jar}
log_debug "$FUNCNAME pmdVersion=$pmdVersion moduleJavadocJar=$moduleJavadocJar module=$module"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion moduleJavadocJar=$moduleJavadocJar module=$module"
scp "$moduleJavadocJar" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH}
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH} && \
mkdir -p apidocs/${module}/${pmdVersion} && \
unzip -qo -d apidocs/${module}/${pmdVersion} ${moduleJavadocJarBasename} && \
rm ${moduleJavadocJarBasename}"
log_info "JavaDoc for $module uploaded: https://docs.pmd-code.org/apidocs/${module}/${pmdVersion}/"
}
function pmd_code_fixPmdLangTestStyle {
local basePath="$1"
log_debug "$FUNCNAME basePath=$basePath"
scp "${basePath}/pmd-lang-test/target/dokka/style.css" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH}/apidocs/pmd-lang-test/
log_info "Fixed style for https://docs.pmd-code.org/apidocs/pmd-lang-test/*/"
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \
mkdir -p \"apidocs/${module}/${pmdVersion}\" && \
unzip -qo -d \"apidocs/${module}/${pmdVersion}\" \"${moduleJavadocJarBasename}\" && \
rm \"${moduleJavadocJarBasename}\""
pmd_ci_log_info "JavaDoc for $module uploaded: https://docs.pmd-code.org/apidocs/${module}/${pmdVersion}/"
}
function pmd_code_removeJavadoc() {
local pmdVersion="$1"
local -r pmdVersion="$1"
log_debug "$FUNCNAME pmdVersion=$pmdVersion"
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd ${PMD_CODE_DOCS_PATH} && \
rm -rf apidocs/*/${pmdVersion}"
log_info "Removed Javadoc: https://docs.pmd-code.org/apidocs/*/${pmdVersion}/ is gone"
pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion"
# shellcheck disable=SC2029
ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \
rm -rf apidocs/*/\"${pmdVersion}\""
pmd_ci_log_info "Removed Javadoc: https://docs.pmd-code.org/apidocs/*/${pmdVersion}/ is gone"
}

View File

@ -1,3 +1,9 @@
#!/usr/bin/env bash
MODULE="pmd-doc"
SCRIPT_INCLUDES="log.bash"
# shellcheck source=inc/fetch_ci_scripts.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
# Used env vars:
# PMD_CI_JOB_URL
@ -9,44 +15,44 @@
# The documentation will be generated in the directory "docs/_site".
#
function pmd_doc_generate_jekyll_site() {
pushd docs
pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; }
echo -e "\n\n"
log_info "Building documentation using jekyll..."
pmd_ci_log_info "Building documentation using jekyll..."
bundle config set --local path vendor/bundle
bundle install
bundle exec jekyll build
popd
popd || exit 1
}
#
# Creates the pmd-doc.zip archive. It will be placed in "docs/".
#
function pmd_doc_create_archive() {
pushd docs
pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; }
echo -e "\n\n"
log_info "Creating pmd-doc archive..."
mv _site pmd-doc-${VERSION}
zip -qr pmd-doc-${VERSION}.zip pmd-doc-${VERSION}/
log_success "Successfully created pmd-doc-${VERSION}.zip"
pmd_ci_log_info "Creating pmd-doc archive..."
mv _site "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}"
zip -qr "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}.zip" "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/"
pmd_ci_log_success "Successfully created pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}.zip"
popd
popd || exit 1
}
#
# Publishes the site to https://pmd.github.io/pmd-${VERSION} and
# Publishes the site to https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} and
# https://pmd.github.io/latest/
#
function publish_release_documentation_github() {
echo -e "\n\n"
log_info "Adding the new doc to pmd.github.io..."
pmd_ci_log_info "Adding the new doc to pmd.github.io..."
# clone pmd.github.io. Note: This uses the ssh key setup earlier
# In order to speed things up, we use a sparse checkout - no need to checkout all directories here
mkdir pmd.github.io
(
cd pmd.github.io
cd pmd.github.io || { echo "Directory 'pmd.github.io' doesn't exist"; exit 1; }
git init
git config user.name "PMD CI (pmd-bot)"
git config user.email "andreas.dangel+pmd-bot@adangel.org"
@ -55,30 +61,30 @@ function publish_release_documentation_github() {
echo "/latest/" > .git/info/sparse-checkout
echo "/sitemap.xml" >> .git/info/sparse-checkout
git pull --depth=1 origin master
log_info "Copying documentation from ../docs/pmd-doc-${VERSION}/ to pmd-${VERSION}/ ..."
rsync -ah --stats ../docs/pmd-doc-${VERSION}/ pmd-${VERSION}/
pmd_ci_log_info "Copying documentation from ../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ to pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/ ..."
rsync -ah --stats "../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/"
git status
echo "Executing: git add pmd-${VERSION}"
git add pmd-${VERSION}
echo "Executing: git commit..."
git commit -q -m "Added pmd-${VERSION}"
pmd_ci_log_debug "Executing: git add pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
git add "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
pmd_ci_log_debug "Executing: git commit..."
git commit -q -m "Added pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
log_info "Copying pmd-${VERSION} to latest ..."
pmd_ci_log_info "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest ..."
git rm -qr latest
cp -a pmd-${VERSION} latest
echo "Executing: git add latest"
cp -a "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" latest
pmd_ci_log_debug "Executing: git add latest"
git add latest
echo "Executing: git commit..."
git commit -q -m "Copying pmd-${VERSION} to latest"
pmd_ci_log_debug "Executing: git commit..."
git commit -q -m "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest"
log_info "Generating sitemap.xml"
pmd_ci_log_info "Generating sitemap.xml"
../docs/sitemap_generator.sh > sitemap.xml
echo "Executing: git add sitemap.xml"
pmd_ci_log_debug "Executing: git add sitemap.xml"
git add sitemap.xml
echo "Executing: git commit..."
pmd_ci_log_debug "Executing: git commit..."
git commit -q -m "Generated sitemap.xml"
echo "Executing: git push origin master"
pmd_ci_log_info "Executing: git push origin master"
git push origin master
)
}
@ -89,14 +95,14 @@ function publish_release_documentation_github() {
#
function pmd_doc_publish_to_github_pages() {
echo -e "\n\n"
log_info "Pushing the new site to github pages..."
pmd_ci_log_info "Pushing the new site to github pages..."
git clone --branch gh-pages --depth 1 git@github.com:pmd/pmd.git pmd-gh-pages
# clear the files first
rm -rf pmd-gh-pages/*
# copy the new site
cp -a docs/pmd-doc-${VERSION}/* pmd-gh-pages/
cp -a "docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}"/* pmd-gh-pages/
(
cd pmd-gh-pages
cd pmd-gh-pages || { echo "Directory 'pmd-gh-pages' doesn't exist"; exit 1; }
git config user.name "PMD CI (pmd-bot)"
git config user.email "andreas.dangel+pmd-bot@adangel.org"
git add -A
@ -106,6 +112,6 @@ ${PMD_CI_JOB_URL}
${PMD_CI_PUSH_COMMIT_COMPARE}"
git commit -q -m "$MSG"
git push git@github.com:pmd/pmd.git HEAD:gh-pages
log_success "Successfully pushed site to https://pmd.github.io/pmd/"
pmd_ci_log_success "Successfully pushed site to https://pmd.github.io/pmd/"
)
}

View File

@ -1,27 +1,30 @@
#
# The functions here require the following scripts:
# inc/logger.inc
# inc/install-openjdk.inc
#!/usr/bin/env bash
MODULE="pmd-doc"
SCRIPT_INCLUDES="log.bash openjdk.bash"
# shellcheck source=inc/fetch_ci_scripts.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
#
# The functions here require the following environment variables:
# PMD_SF_USER
# PMD_CI_BRANCH
#
# DANGER_GITHUB_API_TOKEN
# PMD_CI_CHUNK_TOKEN
function regression_tester_setup_ci() {
# note: building spring needs java8. This is setup already by build.sh/build-pr-win-macos.sh
# note: building spring needs java8. This is setup already by build.sh
gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \
--output .ci/files/public-env .ci/files/public-env.gpg
# shellcheck disable=SC1091
source .ci/files/public-env >/dev/null 2>&1
rm .ci/files/public-env
if hash "bundler" 2>/dev/null; then
log_debug "Bundler is already installed"
pmd_ci_log_debug "Bundler is already installed"
else
log_info "Installing bundler..."
pmd_ci_log_info "Installing bundler..."
gem install bundler
fi
@ -37,50 +40,50 @@ function regression_tester_setup_ci() {
function regression_tester_uploadBaseline() {
local pmdcodeUrl="https://pmd-code.org/pmd-regression-tester/"
local baseline_branch="${PMD_CI_BRANCH:-$PMD_CI_TAG}"
log_debug "$FUNCNAME branch=${baseline_branch}"
pmd_ci_log_debug "${FUNCNAME[0]} branch=${baseline_branch}"
log_info "Generating and uploading baseline for pmdtester (${baseline_branch})..."
pmd_ci_log_info "Generating and uploading baseline for pmdtester (${baseline_branch})..."
pushd ..
rm -f .bundle/config
bundle config set --local gemfile pmd/Gemfile
bundle exec pmdtester \
--mode single \
--local-git-repo ./pmd \
--patch-branch ${baseline_branch} \
--patch-branch "${baseline_branch}" \
--patch-config ./pmd/.ci/files/all-java.xml \
--list-of-project ./pmd/.ci/files/project-list.xml --html-flag \
--error-recovery
pushd target/reports
pushd target/reports || { echo "Directory 'target/reports' doesn't exist"; exit 1; }
BRANCH_FILENAME="${baseline_branch/\//_}"
zip -q -r ${BRANCH_FILENAME}-baseline.zip ${BRANCH_FILENAME}/
# ssh-key for pmd-code.org is setup already by pmd_ci_setup_ssh
scp ${BRANCH_FILENAME}-baseline.zip pmd@pmd-code.org:/httpdocs/pmd-regression-tester/
log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${pmdcodeUrl}"
popd
popd
zip -q -r "${BRANCH_FILENAME}-baseline.zip" "${BRANCH_FILENAME}/"
# ssh-key for pmd-code.org is setup already by pmd_ci_setup_secrets_ssh
scp "${BRANCH_FILENAME}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/
pmd_ci_log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${pmdcodeUrl}"
popd || exit 1
popd || exit 1
}
#
# Execute danger, which executes pmd-regression-tester (via Dangerfile).
#
function regression_tester_executeDanger() {
log_debug "$FUNCNAME"
pmd_ci_log_debug "${FUNCNAME[0]}"
# Create a corresponding remote branch locally
if ! git show-ref --verify --quiet refs/heads/${PMD_CI_BRANCH}; then
git fetch --no-tags --depth=1 origin +refs/heads/${PMD_CI_BRANCH}:refs/remotes/origin/${PMD_CI_BRANCH}
git branch ${PMD_CI_BRANCH} origin/${PMD_CI_BRANCH}
log_debug "Created local branch ${PMD_CI_BRANCH}"
if ! git show-ref --verify --quiet "refs/heads/${PMD_CI_BRANCH}"; then
git fetch --no-tags --depth=1 origin "+refs/heads/${PMD_CI_BRANCH}:refs/remotes/origin/${PMD_CI_BRANCH}"
git branch "${PMD_CI_BRANCH}" "origin/${PMD_CI_BRANCH}"
pmd_ci_log_debug "Created local branch ${PMD_CI_BRANCH}"
fi
# Fetch more commits of the PR for danger and regression tester
git fetch --no-tags --depth=50 origin +$(git rev-parse HEAD^2):
git fetch --no-tags --depth=50 origin "+$(git rev-parse HEAD^2):"
# Fetch more commits from master branch for regression tester
if [[ "${PMD_CI_BRANCH}" != "master" ]]; then
git fetch --no-tags --depth=50 origin +master:
git branch master origin/master
fi
log_info "Running danger on branch ${PMD_CI_BRANCH}"
pmd_ci_log_info "Running danger on branch ${PMD_CI_BRANCH}"
bundle exec danger --verbose
log_success "Executed danger successfully"
pmd_ci_log_success "Executed danger successfully"
}

View File

@ -1,62 +0,0 @@
function pmd_ci_setup_private_env() {
log_info "Setting up secrets as environment variables..."
local -r ENV_FILE=.ci/files/private-env
printenv PMD_CI_SECRET_PASSPHRASE | gpg --batch --yes --decrypt \
--passphrase-fd 0 \
--output ${ENV_FILE} ${ENV_FILE}.gpg
source ${ENV_FILE} >/dev/null 2>&1
rm ${ENV_FILE}
}
function pmd_ci_setup_gpg_key() {
log_info "Setting up GPG release signing key..."
local -r GPG_FILE=.ci/files/release-signing-key-D0BF1D737C9A1C22.gpg
mkdir -p "${HOME}/.gpg"
printenv PMD_CI_SECRET_PASSPHRASE | gpg --batch --yes --decrypt \
--passphrase-fd 0 \
--output ${GPG_FILE} ${GPG_FILE}.gpg
gpg --batch --import ${GPG_FILE}
rm ${GPG_FILE}
}
function pmd_ci_setup_ssh() {
log_info "Setting up .ssh/id_rsa..."
local -r SSH_KEY_FILE=.ci/files/id_rsa
printenv PMD_CI_SECRET_PASSPHRASE | gpg --batch --yes --decrypt \
--passphrase-fd 0 \
--output ${SSH_KEY_FILE} ${SSH_KEY_FILE}.gpg
chmod 600 ${SSH_KEY_FILE}
mkdir -p ${HOME}/.ssh
chmod 700 "${HOME}/.ssh"
mv ${SSH_KEY_FILE} "${HOME}/.ssh/id_rsa"
log_info "Setting up .ssh/known_hosts..."
#
# https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/
#
# run locally:
# ssh-keyscan web.sourceforge.net | tee -a known_hosts
#
# verify fingerprints:
# ssh-keygen -F web.sourceforge.net -l -f known_hosts
# # Host web.sourceforge.net found: line 1
# web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90
# # Host web.sourceforge.net found: line 2
# web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY
# # Host web.sourceforge.net found: line 3
# web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY
#
# then add output of `ssh-keygen -F web.sourceforge.net -f known_hosts`
#
echo 'web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==' >> "$HOME/.ssh/known_hosts"
echo 'web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo=' >> "$HOME/.ssh/known_hosts"
echo 'web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC' >> "$HOME/.ssh/known_hosts"
# add pmd-code.org (ssh-keyscan pmd-code.org)
echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' >> $HOME/.ssh/known_hosts
}

View File

@ -1,166 +0,0 @@
#
# The functions here require the following scripts:
# logger.inc
#
# The functions here require the following environment variables:
# PMD_SF_USER
# PMD_SF_APIKEY
#
#
# Uploads the release notes to sourceforge files as "ReadMe.md".
#
# Note: this function always succeeds, even if the upload fails.
# In that case, just a error logging is provided.
#
function sourceforge_uploadReleaseNotes() {
local pmdVersion="$1"
local releaseNotes="$2"
log_debug "$FUNCNAME pmdVersion=$pmdVersion"
local targetUrl="https://sourceforge.net/projects/pmd/files/pmd/${pmdVersion}"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function release_notes_fail() {
log_error "Error while uploading release notes as ReadMe.md to sourceforge!"
log_error "Please upload manually: ${targetUrl}"
cleanup_temp_dir
}
function cleanup_temp_dir() {
log_debug "Cleanup tempdir $releaseNotesTempDir"
rm "${releaseNotesTempDir}/${pmdVersion}/ReadMe.md" || true
rmdir "${releaseNotesTempDir}/${pmdVersion}" || true
rmdir "${releaseNotesTempDir}" || true
}
# exit subshell after trap
set -e
trap release_notes_fail ERR
local releaseNotesTempDir=$(mktemp -d)
log_debug "Tempdir: $releaseNotesTempDir"
mkdir -p "${releaseNotesTempDir}/${pmdVersion}"
echo "$releaseNotes" > "${releaseNotesTempDir}/${pmdVersion}/ReadMe.md"
log_info "Uploading release notes to sourceforge for version $pmdVersion"
rsync -avz \
"${releaseNotesTempDir}/" \
"${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/pmd/"
log_success "Successfully uploaded release notes as ReadMe.md to sourceforge: ${targetUrl}"
cleanup_temp_dir
)
# restore errexit state
eval "$errexitstate"
}
#
# Uploads the given file to sourceforge.
#
# Note: This function always succeeds, even if the upload fails.
# In that case, just a error logging is provided.
#
function sourceforge_uploadFile() {
local pmdVersion="$1"
local filename="$2"
log_debug "$FUNCNAME pmdVersion=$pmdVersion filename=$filename"
local targetUrl="https://sourceforge.net/projects/pmd/files/pmd/${pmdVersion}"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function upload_failed() {
log_error "Error while uploading ${filename} to sourceforge!"
log_error "Please upload manually: ${targetUrl}"
}
# exit subshell after trap
set -e
trap upload_failed ERR
log_info "Uploading $filename to sourceforge..."
.ci/travis_wait "rsync -avh ${filename} ${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/pmd/${pmdVersion}/"
log_success "Successfully uploaded ${filename} to sourceforge: ${targetUrl}"
)
# restore errexit state
eval "$errexitstate"
}
#
# Select the given version as the new default download.
#
# Note: This function always succeeds, even if the request fails.
# In that case, just a error logging is provided.
#
function sourceforge_selectDefault() {
local pmdVersion="$1"
log_debug "$FUNCNAME pmdVersion=$pmdVersion"
local targetUrl="https://sourceforge.net/projects/pmd/files/pmd/${pmdVersion}"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function request_failed() {
log_error "Error while selecting ${pmdVersion} as new default download on sourceforge!"
log_error "Please do it manually: ${targetUrl}"
}
# exit subshell after trap
set -e
trap request_failed ERR
log_info "Selecting $pmdVersion as new default on sourceforge..."
local response
response=$(curl --fail -s -H "Accept: application/json" \
-X PUT \
-d "api_key=${PMD_SF_APIKEY}" \
-d "default=windows&default=mac&default=linux&default=bsd&default=solaris&default=others" \
"https://sourceforge.net/projects/pmd/files/pmd/${pmdVersion}/pmd-bin-${pmdVersion}.zip")
log_debug " -> response: $response"
log_success "Successfully selected $pmdVersion as new default on sourceforge: ${targetUrl}"
)
# restore errexit state
eval "$errexitstate"
}
#
# Rsyncs the complete documentation to sourceforge.
#
# Note: This function always succeeds, even if the upload fails.
# In that case, just a error logging is provided.
#
function sourceforge_rsyncSnapshotDocumentation() {
local pmdVersion="$1"
local targetPath="$2"
log_debug "$FUNCNAME pmdVersion=$pmdVersion targetPath=$targetPath"
local targetUrl="https://pmd.sourceforge.io/${targetPath}/"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function upload_failed() {
log_error "Couldn't upload the documentation. It won't be current on ${targetUrl}"
}
# exit subshell after trap
set -e
trap upload_failed ERR
log_info "Uploading documentation to ${targetUrl}..."
.ci/travis_wait "rsync -ah --stats --delete docs/pmd-doc-${VERSION}/ ${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/snapshot/"
log_success "Successfully uploaded documentation: ${targetUrl}"
)
# restore errexit state
eval "$errexitstate"
}

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,6 @@
- [ ] Added unit tests for fixed bug/feature
- [ ] Passing all unit tests
- [ ] Complete build `./mvnw clean verify` passes (checked automatically by travis)
- [ ] Complete build `./mvnw clean verify` passes (checked automatically by github actions)
- [ ] Added (in-code) documentation (if needed)

60
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,60 @@
name: build
on:
push:
branches:
- main
- master
- pmd/7.0.x
tags:
- '**'
pull_request:
schedule:
# build it monthly: At 04:00 on day-of-month 1.
- cron: '0 4 1 * *'
jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: false
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: actions/cache@v2
with:
path: |
~/.m2/repository
~/.cache
vendor/bundle
key: ${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-
- name: Set up Ruby 2.7
uses: actions/setup-ruby@v1
with:
ruby-version: 2.7
- name: Setup Environment
shell: bash
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "MAVEN_OPTS=-Dmaven.wagon.httpconnectionManager.ttlSeconds=180 -Dmaven.wagon.http.retryHandler.count=3 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/11/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |
f=check-environment.sh; \
mkdir -p .ci && \
( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \
chmod 755 .ci/$f && \
.ci/$f
- name: Build
run: .ci/build.sh
shell: bash
env:
PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

28
.github/workflows/git-repo-sync.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: git-repo-sync
on:
push:
branches:
- main
- master
tags:
- '**'
jobs:
build:
runs-on: ubuntu-latest
continue-on-error: false
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Setup Environment
shell: bash
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/11/scripts" >> $GITHUB_ENV
- name: Sync
run: .ci/git-repo-sync.sh
shell: bash
env:
PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }}

Some files were not shown because too many files have changed in this diff Show More