jenkinsci / github-checks-plugin

Jenkins Plugin for GitHub Checks API
https://plugins.jenkins.io/github-checks/
MIT License
79 stars 38 forks source link

Failed Publishing GitHub checks - Only 65535 characters are allowed; 65537 were supplied. #345

Open jankosecki opened 1 year ago

jankosecki commented 1 year ago

Jenkins and plugins versions report

Environment ```text Jenkins: 2.401.1 OS: Linux - 5.15.0-1026-aws Java: 11.0.19 - Eclipse Adoptium (OpenJDK 64-Bit Server VM) --- ansicolor:1.0.2 antisamy-markup-formatter:159.v25b_c67cd35fb_ apache-httpcomponents-client-4-api:4.5.14-150.v7a_b_9d17134a_5 authentication-tokens:1.53.v1c90fd9191a_b_ authorize-project:1.7.0 aws-credentials:191.vcb_f183ce58b_9 aws-java-sdk:1.12.447-382.vda_68e2007233 aws-java-sdk-cloudformation:1.12.447-382.vda_68e2007233 aws-java-sdk-codebuild:1.12.447-382.vda_68e2007233 aws-java-sdk-ec2:1.12.447-382.vda_68e2007233 aws-java-sdk-ecr:1.12.447-382.vda_68e2007233 aws-java-sdk-ecs:1.12.447-382.vda_68e2007233 aws-java-sdk-efs:1.12.447-382.vda_68e2007233 aws-java-sdk-elasticbeanstalk:1.12.447-382.vda_68e2007233 aws-java-sdk-iam:1.12.447-382.vda_68e2007233 aws-java-sdk-kinesis:1.12.447-382.vda_68e2007233 aws-java-sdk-logs:1.12.447-382.vda_68e2007233 aws-java-sdk-minimal:1.12.447-382.vda_68e2007233 aws-java-sdk-sns:1.12.447-382.vda_68e2007233 aws-java-sdk-sqs:1.12.447-382.vda_68e2007233 aws-java-sdk-ssm:1.12.447-382.vda_68e2007233 basic-branch-build-strategies:71.vc1421f89888e blueocean:1.27.4 blueocean-bitbucket-pipeline:1.27.4 blueocean-commons:1.27.4 blueocean-config:1.27.4 blueocean-core-js:1.27.4 blueocean-dashboard:1.27.4 blueocean-display-url:2.4.2 blueocean-events:1.27.4 blueocean-git-pipeline:1.27.4 blueocean-github-pipeline:1.27.4 blueocean-i18n:1.27.4 blueocean-jwt:1.27.4 blueocean-personalization:1.27.4 blueocean-pipeline-api-impl:1.27.4 blueocean-pipeline-editor:1.27.4 blueocean-pipeline-scm-api:1.27.4 blueocean-rest:1.27.4 blueocean-rest-impl:1.27.4 blueocean-web:1.27.4 bootstrap5-api:5.3.0-1 bootstraped-multi-test-results-report:2.2.1 bouncycastle-api:2.28 branch-api:2.1105.v472604208c55 build-monitor-plugin:1.14-717.v3efcdffe8d58 build-pipeline-plugin:1.5.8 caffeine-api:3.1.6-115.vb_8b_b_328e59d8 checks-api:2.0.0 cloudbees-bitbucket-branch-source:805.v7f97d29dc0f5 cloudbees-folder:6.815.v0dd5a_cb_40e0e command-launcher:90.v669d7ccb_7c31 commons-lang3-api:3.12.0-36.vd97de6465d5b_ commons-text-api:1.10.0-36.vc008c8fcda_7b_ config-file-provider:938.ve2b_8a_591c596 credentials:1254.vb_96f366e7b_a_d credentials-binding:604.vb_64480b_c56ca_ dark-theme:315.va_22e7d692ea_a dashboard-view:2.487.vcf0ff9008a_c0 dependency-check-jenkins-plugin:5.4.0 display-url-api:2.3.7 docker-commons:419.v8e3cd84ef49c docker-workflow:563.vd5d2e5c4007f durable-task:507.v050055d0cb_dd echarts-api:5.4.0-5 extended-choice-parameter:373.v1a_ecea_fdf2a_a_ favorite:2.4.2 font-awesome-api:6.4.0-1 git:5.0.2 git-client:4.3.0 github:1.37.1 github-api:1.314-431.v78d72a_3fe4c3 github-branch-source:1703.vd5a_2b_29c6cdc github-checks:545.v79a_a_68b_ca_682 github-oauth:0.39 global-build-stats:269.v214f74360b_3a_ gradle:2.7 handy-uri-templates-2-api:2.1.8-22.v77d5b_75e6953 htmlpublisher:1.31 instance-identity:142.v04572ca_5b_265 ionicons-api:56.v1b_1c8c49374e jackson2-api:2.15.1-344.v6eb_55303dc3e jakarta-activation-api:2.0.1-3 jakarta-mail-api:2.0.1-3 javax-activation-api:1.2.0-6 javax-mail-api:1.6.2-8 jaxb:2.3.8-1 jdk-tool:63.v62d2fd4b_4793 jenkins-design-language:1.27.4 jjwt-api:0.11.5-77.v646c772fddb_0 jquery:1.12.4-1 jquery3-api:3.7.0-1 junit:1207.va_09d5100410f kubernetes:3937.vd7b_82db_e347b_ kubernetes-client-api:6.4.1-215.v2ed17097a_8e9 kubernetes-credentials:0.10.0 leastload:3.0.0 mailer:457.v3f72cb_e015e5 material-theme:0.5.2-rc100.6121925fe229 matrix-auth:3.1.8 matrix-project:789.v57a_725b_63c79 metrics:4.2.18-438.v0ede325a_4c68 mina-sshd-api-common:2.10.0-69.v28e3e36d18eb_ mina-sshd-api-core:2.10.0-69.v28e3e36d18eb_ nodejs:1.6.0 okhttp-api:4.10.0-132.v7a_7b_91cef39c parameterized-trigger:2.45 pipeline-aws:1.43 pipeline-build-step:491.v1fec530da_858 pipeline-graph-analysis:202.va_d268e64deb_3 pipeline-groovy-lib:656.va_a_ceeb_6ffb_f7 pipeline-input-step:468.va_5db_051498a_4 pipeline-milestone-step:111.v449306f708b_7 pipeline-model-api:2.2133.ve46a_6113dfc3 pipeline-model-definition:2.2133.ve46a_6113dfc3 pipeline-model-extensions:2.2133.ve46a_6113dfc3 pipeline-npm:49.v9c8598493533 pipeline-rest-api:2.32 pipeline-stage-step:305.ve96d0205c1c6 pipeline-stage-tags-metadata:2.2133.ve46a_6113dfc3 pipeline-stage-view:2.32 pipeline-utility-steps:2.15.4 plain-credentials:143.v1b_df8b_d3b_e48 plugin-util-api:3.3.0 preSCMbuildstep:71.v1f2990a_37e27 pubsub-light:1.17 scm-api:672.v64378a_b_20c60 script-security:1251.vfe552ed55f8d simple-theme-plugin:160.vb_76454b_67900 slack:664.vc9a_90f8b_c24a_ snakeyaml-api:1.33-95.va_b_a_e3e47b_fa_4 solarized-theme:0.1 sonar:2.15 sse-gateway:1.26 ssh-agent:333.v878b_53c89511 ssh-credentials:305.v8f4381501156 sshd:3.249.v2dc2ea_416e33 structs:324.va_f5d6774f3a_d test-results-analyzer:0.4.0 theme-manager:193.vcef22f6c5f2b_ timestamper:1.25 token-macro:359.vb_cde11682e0c trilead-api:2.84.v72119de229b_7 uno-choice:2.6.5 variant:59.vf075fe829ccb workflow-aggregator:596.v8c21c963d92d workflow-api:1213.v646def1087f9 workflow-basic-steps:1017.vb_45b_302f0cea_ workflow-cps:3673.v5b_dd74276262 workflow-durable-task-step:1247.v7f9dfea_b_4fd0 workflow-job:1308.v58d48a_763b_31 workflow-multibranch:746.v05814d19c001 workflow-scm-step:408.v7d5b_135a_b_d49 workflow-step-api:639.v6eca_cd8c04a_a_ workflow-support:839.v35e2736cfd5c ```

What Operating System are you using (both controller, and any agents involved in the problem)?

Jenkins controller runs as a pod in K8s cluster with agents being managed ad-hoc via Kubernetes plugin

Reproduction steps

  1. We have a react native pipeline that uses a container with a full Android Toolchain that allows us to run ./gradlew --no-daemon -PreactNativeArchitectures=x86_64 assembleDebug
  2. PR build fails (expected) and generates a very long console output
  3. GitHub Check plugin fails to upload check to GitHub

Expected Results

GitHub Checks plugin manages to truncate the output and upload a check to GitHub

Actual Results

Final Jenkins check is not being published to GitHub due to:

ERROR: script returned exit code 1
[GitHub Checks] Failed Publishing GitHub checks: org.kohsuke.github.HttpException: {"message":"Invalid request.\n\nOnly 65535 characters are allowed; 65537 were supplied.","documentation_url":"https://docs.github.com/rest/reference/checks#update-a-check-run"}

Anything else?

I find it interesting that supplier characters (65537) are only +2 from the max allowed (65535). It would be quite a coincidence that output of my build exceeds the allowed characters by just 2.

I read somewhere that Check plugin is using TruncatedString to ensure that uploaded string does not exceed the max allowed value - I wonder if there is so sort of mistake in the truncation logic, which then results in truncated string to by bigger by 2 from the allowed value.

Note: for now I've used "Suppress log output in checks" of my GitHub Organization folder to avoid the issue

KalleOlaviNiemitalo commented 1 year ago

Related Java code:

but I wonder if GitHub also counts the quotation marks around the string. I hope not!

It would be interesting to log the actual GitHub API request and count the bytes from that.

jankosecki commented 1 year ago

Is there an easy way to log the request? I could do it when I have some free time.

But I never debugged any jenkins or plugin related issues so not sure what the correct troubleshooting steps are.

Edit: actually, would probably make sense to replace deprecated call TruncatedString.build() with TruncatedString.buildByChars()

timja commented 1 year ago

Could work around it by just adding a - 3 somewhere as an extra buffer.

KalleOlaviNiemitalo commented 1 year ago

replace deprecated call TruncatedString.build() with TruncatedString.buildByChars()

No, if it's replaced, then it must use buildByBytes, because the GitHub limit is 65535 bytes, not 65535 characters. Although really the choice on chars vs. bytes should be made by github-checks-plugin rather than checks-api-plugin.

jankosecki commented 1 year ago

replace deprecated call TruncatedString.build() with TruncatedString.buildByChars()

No, if it's replaced, then it must use buildByBytes, because the GitHub limit is 65535 bytes, not 65535 characters. Although really the choice on chars vs. bytes should be made by github-checks-plugin rather than checks-api-plugin.

According to GitHub docs, they say it's a limit of 65535 characters but could be also incorrectly written doc.

KalleOlaviNiemitalo commented 1 year ago

Re logging: I think the HTTP request goes to https://github.com/hub4j/github-api/blob/github-api-1.314/src/main/java/org/kohsuke/github/internal/DefaultGitHubConnector.java, and on Java 11, that chooses https://github.com/hub4j/github-api/blob/github-api-1.314/src/main/java11/org/kohsuke/github/extras/HttpClientGitHubConnector.java, which uses java.net.http.HttpClient. https://stackoverflow.com/a/53231046 suggests logging can be configured via the jdk.httpclient.HttpClient.log system property.

KalleOlaviNiemitalo commented 1 year ago

they say it's a limit of 65535 characters

Perhaps they changed it. In https://github.com/jenkinsci/github-checks-plugin/issues/131#issuecomment-785254749, the error message said "summary exceeds a maximum bytesize of 65535". You instead got "Only 65535 characters are allowed". Anyway, each character is at least one byte, so if the number of bytes is limited to 65535, then the request will fit in a 65535-character limit as well.

KalleOlaviNiemitalo commented 1 year ago

Or, perhaps they count bytes for the summary but characters for the text. 👀