@@ -1,26 +0,0 @@ | |||
name: Dogfood merge | |||
on: | |||
push: | |||
branches: | |||
- master | |||
- "dogfood/**" | |||
jobs: | |||
dogfood_merge: | |||
# prevent job to run on public repository sonarsource/sonarqube | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: Update dogfood-on-next branch | |||
steps: | |||
- name: Merge dogfood and master branches | |||
uses: SonarSource/gh-action_dogfood_merge@v1 | |||
env: | |||
GITHUB_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
with: | |||
dogfood-branch: "dogfood-on-next" | |||
- name: Notify failures on Slack | |||
if: failure() | |||
uses: Ilshidur/action-slack@2.0.0 | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Failed to merge dogfood and master branches, see the logs at https://github.com/SonarSource/sonar-enterprise/actions" |
@@ -1,29 +0,0 @@ | |||
name: Nightly QA | |||
on: | |||
schedule: | |||
# at 1:30 daily | |||
- cron: "30 1 * * *" | |||
jobs: | |||
nightly: | |||
# prevent job to run on public repository sonarsource/sonarqube | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: Trigger the nightly QA build | |||
steps: | |||
- name: Fetch code | |||
uses: actions/checkout@v2 | |||
with: | |||
token: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
ref: branch-nightly-build | |||
path: repo | |||
- name: Trigger nightly build | |||
run: | | |||
cd repo/ | |||
./private/trigger-nightly-build.sh | |||
- name: Notify failures on Slack | |||
if: failure() | |||
uses: Ilshidur/action-slack@2.0.0 | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Nightly QA failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions" |
@@ -1,60 +0,0 @@ | |||
name: Release | |||
# This workflow is triggered when publishing a GitHub release | |||
on: | |||
release: | |||
types: | |||
- published | |||
env: | |||
PYTHONUNBUFFERED: 1 | |||
jobs: | |||
release: | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: Start release process | |||
timeout-minutes: 60 | |||
steps: | |||
- name: Run release action | |||
id: run_release | |||
uses: SonarSource/gh-action_LT_release@v2 | |||
with: | |||
distribute: true | |||
publish_to_binaries: true | |||
attach_artifacts_to_github_release: false | |||
run_rules_cov: false | |||
slack_channel: sonarqube-build | |||
env: | |||
ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }} | |||
BINTRAY_USER: ${{ secrets.BINTRAY_USER }} | |||
BINTRAY_TOKEN: ${{ secrets.BINTRAY_TOKEN }} | |||
BURGRX_USER: ${{ secrets.BURGRX_USER }} | |||
BURGRX_PASSWORD: ${{ secrets.BURGRX_PASSWORD }} | |||
CENTRAL_USER: ${{ secrets.CENTRAL_USER }} | |||
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} | |||
CIRRUS_TOKEN: ${{ secrets.CIRRUS_TOKEN }} | |||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |||
PATH_PREFIX: ${{ secrets.BINARIES_PATH_PREFIX }} | |||
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} | |||
RELEASE_SSH_USER: ${{ secrets.RELEASE_SSH_USER }} | |||
RELEASE_SSH_KEY: ${{ secrets.RELEASE_SSH_KEY }} | |||
SLACK_API_TOKEN: ${{secrets.SLACK_API_TOKEN }} | |||
- name: Log outputs | |||
if: always() | |||
run: | | |||
echo "${{ steps.run_release.outputs.releasability }}" | |||
echo "${{ steps.run_release.outputs.release }}" | |||
echo "${{ steps.run_release.outputs.distribute_release }}" | |||
- name: Notify success on Slack | |||
uses: Ilshidur/action-slack@2.0.0 | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Release successful for {{ GITHUB_REPOSITORY }} by {{ GITHUB_ACTOR }}" | |||
- name: Notify failures on Slack | |||
uses: Ilshidur/action-slack@2.0.0 | |||
if: failure() | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Release failed, see the logs at https://github.com/{{ GITHUB_REPOSITORY }}/actions by {{ GITHUB_ACTOR }}" |
@@ -1,37 +0,0 @@ | |||
name: Suggest dependency upgrades | |||
on: | |||
# use push to test the bot | |||
# push: | |||
# branches-ignore: | |||
# - 'bot/upgrade_plugins**' | |||
schedule: | |||
# at 5:00 every Monday | |||
- cron: '0 5 * * MON' | |||
jobs: | |||
suggest-upgrades-job: | |||
# prevent job to run on public repository sonarsource/sonarqube (on which GitHub Actions are disabled) | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: List available upgrades | |||
steps: | |||
- uses: actions/checkout@v2 | |||
with: | |||
fetch-depth: 1 | |||
ref: master | |||
- name: Set up JDK | |||
uses: actions/setup-java@v1 | |||
with: | |||
java-version: 11 | |||
- name: Cache Gradle Wrapper | |||
uses: actions/cache@v1 | |||
with: | |||
path: ~/.gradle/wrapper | |||
key: ${{ runner.os }}-gradlew-${{ hashFiles('**/*.zip') }} | |||
restore-keys: ${{ runner.os }}-gradlew | |||
- name: Find upgrades | |||
env: | |||
ARTIFACTORY_PRIVATE_USERNAME: ${{ secrets.REPOX_LOGIN }} | |||
ARTIFACTORY_PRIVATE_PASSWORD: ${{ secrets.REPOX_API_KEY }} | |||
run: | | |||
./gradlew dependencyUpdates yarn_audit -Drevision=release |
@@ -1,30 +0,0 @@ | |||
name: Sync LTS branch | |||
on: | |||
schedule: | |||
# at 20:00 daily | |||
- cron: "0 20 * * *" | |||
jobs: | |||
sync_lts: | |||
# prevent job to run on public repository sonarsource/sonarqube | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: Sync LTS branch of sonarsource/sonar-enterprise with sonarsource/sonarqube | |||
steps: | |||
- name: Fetch code | |||
uses: actions/checkout@v2 | |||
with: | |||
token: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
ref: master | |||
path: repo | |||
- name: Sync LTS branch | |||
run: ./repo/private/sync-public-git-branches.sh | |||
env: | |||
GITHUB_ORG_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
BRANCH_NAME: branch-7.9 | |||
- name: Notify failures on Slack | |||
if: failure() | |||
uses: Ilshidur/action-slack@2.0.0 | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Nightly public sync failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions" |
@@ -1,30 +0,0 @@ | |||
name: Sync master branch | |||
on: | |||
schedule: | |||
# at 20:00 daily | |||
- cron: "0 20 * * *" | |||
jobs: | |||
sync_master: | |||
# prevent job to run on public repository sonarsource/sonarqube | |||
if: github.repository == 'sonarsource/sonar-enterprise' | |||
runs-on: ubuntu-latest | |||
name: Sync master branch of sonarsource/sonar-enterprise with sonarsource/sonarqube | |||
steps: | |||
- name: Fetch code | |||
uses: actions/checkout@v2 | |||
with: | |||
token: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
ref: master | |||
path: repo | |||
- name: Sync master branch | |||
run: ./repo/private/sync-public-git-branches.sh | |||
env: | |||
GITHUB_ORG_TOKEN: ${{ secrets.GITHUB_ORG_TOKEN }} | |||
BRANCH_NAME: master | |||
- name: Notify failures on Slack | |||
if: failure() | |||
uses: Ilshidur/action-slack@2.0.0 | |||
env: | |||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |||
with: | |||
args: "Nightly public sync failed, see the logs at https://github.com/SonarSource/sonar-enterprise/actions" |
@@ -61,7 +61,7 @@ import static org.sonar.core.util.FileUtils.deleteQuietly; | |||
import static org.sonar.scanner.scan.branch.BranchType.PULL_REQUEST; | |||
public class ReportPublisher implements Startable { | |||
private static final int DEFAULT_WRITE_TIMEOUT = 30_000; | |||
private static final Logger LOG = Loggers.get(ReportPublisher.class); | |||
private static final String CHARACTERISTIC = "characteristic"; | |||
private static final String DASHBOARD = "dashboard"; | |||
@@ -200,6 +200,7 @@ public class ReportPublisher implements Startable { | |||
WsResponse response; | |||
try { | |||
post.setWriteTimeOutInMs(DEFAULT_WRITE_TIMEOUT); | |||
response = wsClient.call(post).failIfNotSuccessful(); | |||
} catch (HttpException e) { | |||
throw MessageException.of(String.format("Failed to upload report - %s", DefaultScannerWsClient.createErrorMessage(e))); |
@@ -53,6 +53,7 @@ import org.sonarqube.ws.client.WsResponse; | |||
import static org.apache.commons.io.FileUtils.readFileToString; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.ArgumentMatchers.any; | |||
import static org.mockito.ArgumentMatchers.argThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
@@ -94,6 +95,18 @@ public class ReportPublisherTest { | |||
.resolve("report-task.txt")); | |||
} | |||
@Test | |||
public void use_30s_write_timeout() { | |||
MockWsResponse submitMockResponse = new MockWsResponse(); | |||
submitMockResponse.setContent(Ce.SubmitResponse.newBuilder().setTaskId("task-1234").build().toByteArray()); | |||
when(wsClient.call(any())).thenReturn(submitMockResponse); | |||
underTest.start(); | |||
underTest.execute(); | |||
verify(wsClient).call(argThat(req -> req.getWriteTimeOutInMs().orElse(0) == 30_000)); | |||
} | |||
@Test | |||
public void dump_information_about_report_uploading() throws IOException { | |||
underTest.prepareAndDumpMetadata("TASK-123"); |
@@ -50,7 +50,8 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest { | |||
private final DefaultParameters parameters = new DefaultParameters(); | |||
private final DefaultHeaders headers = new DefaultHeaders(); | |||
private OptionalInt timeOutInMs = OptionalInt.empty(); | |||
private OptionalInt writeTimeOutInMs = OptionalInt.empty(); | |||
BaseRequest(String path) { | |||
this.path = path; | |||
} | |||
@@ -75,6 +76,16 @@ abstract class BaseRequest<SELF extends BaseRequest> implements WsRequest { | |||
return (SELF) this; | |||
} | |||
@Override | |||
public OptionalInt getWriteTimeOutInMs() { | |||
return writeTimeOutInMs; | |||
} | |||
public SELF setWriteTimeOutInMs(int writeTimeOutInMs) { | |||
this.writeTimeOutInMs = OptionalInt.of(writeTimeOutInMs); | |||
return (SELF) this; | |||
} | |||
/** | |||
* Expected media type of response. Default is {@link MediaTypes#JSON}. | |||
*/ |
@@ -164,14 +164,19 @@ public class HttpConnector implements WsConnector { | |||
.newBuilder(); | |||
} | |||
private static OkHttpClient prepareOkHttpClient(OkHttpClient okHttpClient, WsRequest wsRequest) { | |||
if (!wsRequest.getTimeOutInMs().isPresent()) { | |||
static OkHttpClient prepareOkHttpClient(OkHttpClient okHttpClient, WsRequest wsRequest) { | |||
if (!wsRequest.getTimeOutInMs().isPresent() && !wsRequest.getWriteTimeOutInMs().isPresent()) { | |||
return okHttpClient; | |||
} | |||
OkHttpClient.Builder builder = okHttpClient.newBuilder(); | |||
if (wsRequest.getTimeOutInMs().isPresent()) { | |||
builder.readTimeout(wsRequest.getTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS); | |||
} | |||
if (wsRequest.getWriteTimeOutInMs().isPresent()) { | |||
builder.writeTimeout(wsRequest.getWriteTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS); | |||
} | |||
return okHttpClient.newBuilder() | |||
.readTimeout(wsRequest.getTimeOutInMs().getAsInt(), TimeUnit.MILLISECONDS) | |||
.build(); | |||
return builder.build(); | |||
} | |||
private static void completeUrlQueryParameters(BaseRequest<?> request, HttpUrl.Builder urlBuilder) { | |||
@@ -197,7 +202,7 @@ public class HttpConnector implements WsConnector { | |||
try { | |||
return call.execute(); | |||
} catch (IOException e) { | |||
throw new IllegalStateException("Fail to request " + okRequest.url(), e); | |||
throw new IllegalStateException("Fail to request url: " + okRequest.url(), e); | |||
} | |||
} | |||
@@ -35,6 +35,8 @@ public interface WsRequest { | |||
OptionalInt getTimeOutInMs(); | |||
OptionalInt getWriteTimeOutInMs(); | |||
/** | |||
* | |||
* In case of multi value parameters, returns the first value |
@@ -45,6 +45,13 @@ public class BaseRequestTest { | |||
assertThat(underTest.getParams()).isEmpty(); | |||
assertThat(underTest.getMediaType()).isEqualTo(MediaTypes.JSON); | |||
assertThat(underTest.getPath()).isEqualTo("api/foo"); | |||
assertThat(underTest.getWriteTimeOutInMs()).isEmpty(); | |||
} | |||
@Test | |||
public void set_write_timeout() { | |||
underTest.setWriteTimeOutInMs(30_000); | |||
assertThat(underTest.getWriteTimeOutInMs()).hasValue(30_000); | |||
} | |||
@Test |
@@ -30,6 +30,7 @@ import java.util.Random; | |||
import java.util.concurrent.TimeUnit; | |||
import javax.net.ssl.SSLSocketFactory; | |||
import okhttp3.ConnectionSpec; | |||
import okhttp3.OkHttpClient; | |||
import okhttp3.mockwebserver.MockResponse; | |||
import okhttp3.mockwebserver.MockWebServer; | |||
import okhttp3.mockwebserver.RecordedRequest; | |||
@@ -289,6 +290,15 @@ public class HttpConnectorTest { | |||
assertThat(underTest.okHttpClient().connectTimeoutMillis()).isEqualTo(74); | |||
} | |||
@Test | |||
public void override_timeouts_with_request() { | |||
OkHttpClient client = new OkHttpClient.Builder().build(); | |||
WsRequest request = new PostRequest("abc").setWriteTimeOutInMs(123).setTimeOutInMs(234); | |||
client = underTest.prepareOkHttpClient(client, request); | |||
assertThat(client.writeTimeoutMillis()).isEqualTo(123); | |||
assertThat(client.readTimeoutMillis()).isEqualTo(234); | |||
} | |||
@Test | |||
public void send_user_agent() throws Exception { | |||
answerHelloWorld(); |