Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERROR: Failed uploading file to slack #1024

Open
peycho opened this issue Dec 18, 2024 · 0 comments
Open

ERROR: Failed uploading file to slack #1024

peycho opened this issue Dec 18, 2024 · 0 comments

Comments

@peycho
Copy link

peycho commented Dec 18, 2024

Jenkins and plugins versions report

Environment
Jenkins: 2.479.2
OS: Linux - 6.5.0-1020-aws
Java: 21.0.5 - Ubuntu (OpenJDK 64-Bit Server VM)
---
ant:511.v0a_a_1a_334f41b_
antisamy-markup-formatter:162.v0e6ec0fcfcf6
apache-httpcomponents-client-4-api:4.5.14-208.v438351942757
apache-httpcomponents-client-5-api:5.4-124.v31e2987e48f4
asm-api:9.7.1-97.v4cc844130d97
authentication-tokens:1.119.v50285141b_7e1
blueocean:1.27.16
blueocean-bitbucket-pipeline:1.27.16
blueocean-commons:1.27.16
blueocean-config:1.27.16
blueocean-core-js:1.27.16
blueocean-dashboard:1.27.16
blueocean-display-url:2.4.3
blueocean-events:1.27.16
blueocean-git-pipeline:1.27.16
blueocean-github-pipeline:1.27.16
blueocean-i18n:1.27.16
blueocean-jwt:1.27.16
blueocean-personalization:1.27.16
blueocean-pipeline-api-impl:1.27.16
blueocean-pipeline-editor:1.27.16
blueocean-pipeline-scm-api:1.27.16
blueocean-rest:1.27.16
blueocean-rest-impl:1.27.16
blueocean-web:1.27.16
bootstrap5-api:5.3.3-1
bouncycastle-api:2.30.1.78.1-248.ve27176eb_46cb_
branch-api:2.1200.v4b_a_3da_2eb_db_4
build-timeout:1.33
caffeine-api:3.1.8-133.v17b_1ff2e0599
checks-api:2.2.1
cloud-stats:336.v788e4055508b_
cloudbees-bitbucket-branch-source:933.0.2
cloudbees-folder:6.973.vc9b_85a_61e4fc
commons-lang3-api:3.17.0-84.vb_b_938040b_078
commons-text-api:1.12.0-129.v99a_50df237f7
coverage:1.16.1
credentials:1393.v6017143c1763
credentials-binding:687.v619cb_15e923f
dark-theme:514.va_3ea_73d65dc1
data-tables-api:2.1.8-1
display-url-api:2.209.v582ed814ff2f
docker-commons:445.v6b_646c962a_94
docker-workflow:580.vc0c340686b_54
durable-task:581.v299a_5609d767
echarts-api:5.5.1-4
eddsa-api:0.3.0-4.v84c6f0f4969e
email-ext:1861.vdb_d991590994
favorite:2.221.v19ca_666b_62f5
font-awesome-api:6.6.0-2
forensics-api:2.6.0
git:5.6.0
git-client:6.1.0
git-forensics:2.2.1
git-parameter:0.10.0
github:1.40.0
github-api:1.321-478.vc9ce627ce001
github-branch-source:1807.v50351eb_7dd13
github-oauth:621.v33b_4394dda_4d
gradle:2.14
gson-api:2.11.0-85.v1f4e87273c33
handy-uri-templates-2-api:2.1.8-30.v7e777411b_148
htmlpublisher:1.37
instance-identity:201.vd2a_b_5a_468a_a_6
ionicons-api:74.v93d5eb_813d5f
jackson2-api:2.17.0-379.v02de8ec9f64c
jakarta-activation-api:2.1.3-1
jakarta-mail-api:2.1.3-1
javax-activation-api:1.2.0-7
javax-mail-api:1.6.2-10
jaxb:2.3.9-1
jenkins-design-language:1.27.16
jjwt-api:0.11.5-112.ve82dfb_224b_a_d
joda-time-api:2.13.0-93.v9934da_29b_a_e9
jquery3-api:3.7.1-2
json-api:20240303-101.v7a_8666713110
json-path-api:2.9.0-118.v7f23ed82a_8b_8
junit:1311.v39e1716e4eb_e
ldap:770.vb_455e934581a_
mailer:489.vd4b_25144138f
matrix-auth:3.2.3
matrix-project:840.v812f627cb_578
metrics:4.2.21-458.vcf496cb_839e4
mina-sshd-api-common:2.14.0-136.v4d2b_0853615e
mina-sshd-api-core:2.14.0-136.v4d2b_0853615e
okhttp-api:4.11.0-181.v1de5b_83857df
pam-auth:1.11
pipeline-build-step:540.vb_e8849e1a_b_d8
pipeline-github-lib:61.v629f2cc41d83
pipeline-graph-analysis:216.vfd8b_ece330ca_
pipeline-graph-view:382.vb_9a_27b_7b_ea_71
pipeline-groovy-lib:744.v5b_556ee7c253
pipeline-input-step:495.ve9c153f6067b_
pipeline-milestone-step:119.vdfdc43fc3b_9a_
pipeline-model-api:2.2218.v56d0cda_37c72
pipeline-model-definition:2.2218.v56d0cda_37c72
pipeline-model-extensions:2.2218.v56d0cda_37c72
pipeline-stage-step:312.v8cd10304c27a_
pipeline-stage-tags-metadata:2.2218.v56d0cda_37c72
plain-credentials:183.va_de8f1dd5a_2b_
plugin-util-api:5.1.0
prism-api:1.29.0-18
pubsub-light:1.18
resource-disposer:0.25
scm-api:698.v8e3b_c788f0a_6
script-security:1369.v9b_98a_4e95b_2d
slack:751.v2e44153c8fe1
snakeyaml-api:2.3-123.v13484c65210a_
sse-gateway:1.27
ssh-credentials:349.vb_8b_6b_9709f5b_
ssh-slaves:2.1010.v64ec48721231
sshd:3.330.vc866a_8389b_58
structs:338.v848422169819
synopsys-coverity:3.0.5
theme-manager:262.vc57ee4a_eda_5d
timestamper:1.28
token-macro:400.v35420b_922dcb_
trilead-api:2.147.vb_73cc728a_32e
variant:60.v7290fc0eb_b_cd
workflow-aggregator:600.vb_57cdd26fdd7
workflow-api:1336.vee415d95c521
workflow-basic-steps:1058.vcb_fc1e3a_21a_9
workflow-cps:4000.v5198556e9cea_
workflow-durable-task-step:1398.vf6c9e89e5988
workflow-job:1472.ve4d5eca_143c4
workflow-multibranch:795.ve0cb_1f45ca_9a_
workflow-scm-step:427.v4ca_6512e7df1
workflow-step-api:678.v3ee58b_469476
workflow-support:936.v9fa_77211ca_e1
ws-cleanup:0.48
xvnc:1.28

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

Jenkins controller running on Ubuntu 22.04.
Jenkins node running on Ubuntu 22.04 with docker container nodes.

Reproduction steps

Jenkins Pipeline

pipeline {
    environment {
        SLACK_CHANNEL = '#cicd-builds'
    }

    parameters {
        string(name: 'BUILD_BRANCH', defaultValue: 'jenkins-builds', description: 'branch to checkout')
    }

    agent {
        docker {
            image 'ubuntu22_python3.10:22.04'
            args '-u root'
            label 'docker'
        }
    }

    stages {
        stage('Testing') {
            steps {
                sh '''#!/bin/bash
                    set -o errexit
                    set -o pipefail

                    echo "Create test file"
                    echo "$(date) TESTING LINE 1" > testfile.txt
                    echo "$(date) TESTING LINE 2" > testfile.txt
                '''
            }
        }
        stage('Slack') {
            steps {
                script {
                    def filePath = "${env.WORKSPACE}/testfile.txt"
                    def slackResponse = slackSend channel: "${env.SLACK_CHANNEL}", message: 'Uploaded file: testfile.txt', sendAsText: true
                    slackUploadFile filePath: filePath, channel: slackResponse.channelId, initialComment: "Attached file from build ${env.BUILD_NUMBER}"
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}

Expected Results

Post a single short message: Uploaded file: testfile.txt
Upload the example content of file testfile.txt in the same slack channel.

Actual Results

The simple message works.
File upload fail with simple error in Jenkins console.

[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Testing)
[Pipeline] sh
Create test file
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Slack)
[Pipeline] script
[Pipeline] {
[Pipeline] slackSend
Slack Send Pipeline step running, values are - baseUrl: <empty>, teamDomain: https://*****.slack.com/, channel: #cicd-builds, color: <empty>, botUser: true, tokenCredentialId: *****, notifyCommitters: false, iconEmoji: :white_check_mark:, username: cicd-build-bot, timestamp: <empty>
[Pipeline] slackUploadFile
ERROR: Failed uploading file to slack
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] cleanWs
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
[WS-CLEANUP] done
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }

Anything else?

By the look of the Slack documentation there are some changes involved in deprecating the legacy api "files.upload"

The new API works in way different way than the old. It uses 3 steps for uploading a single file into a specific channel.

Example how it works with curl.

echo "$(date) test line 1" >> testfile.txt
echo "$(date) test line 2" >> testfile.txt
echo "$(date) test line 2" >> testfile.txt

ll testfile.txt 
-rw-rw-r-- 1 peycho peycho 132 Dec 18 14:05 testfile.txt

export SLACK_TOKEN="YOUR-SLACK-AUTH-TOKEN"

# Step 1. You can call it metadata step or something like that.
# The required files are token, filename and length.
curl -s https://slack.com/api/files.getUploadURLExternal -F "token=$SLACK_TOKEN" -F "filename=testfile.txt" -F "length=132" | python -m json.tool
{
    "ok": true,
    "upload_url": "https://files.slack.com/upload/v1/CwABAAAAWVERY-LONG-URL",
    "file_id": "F485FFDJK61"
}

# Step 2 upload your file by calling this looong upload_url.
curl -s -X POST https://files.slack.com/upload/v1/CwABAAAAWVERY-LONG-URL -F "token=$SLACK_TOKEN" -F filename="@testfile.txt"

# The response should look like "OK - 132". I guess this is the size of the file and OK means it's uploaded.

# Step 3. Post the file in the channel(s) you want.
curl -s -X POST https://slack.com/api/files.completeUploadExternal -F "token=$SLACK_TOKEN" -F "channel_id=SLACK-CHANNEL-ID" -F "initial_comment=comment=Testing" -F "files=[{'id': 'F485FFDJK61', 'title': 'testfile.txt' }]" | python -m json.tool

The output of the last curl should look like this:

{
    "ok": true,
    "files": [
        {
            "id": "*************",
            "created": 1734524521,
            "timestamp": 1734524521,
            "name": "testfile.txt",
            "title": "testfile.txt",
            "mimetype": "text/plain",
            "filetype": "text",
            "pretty_type": "Plain Text",
            "user": "**********",
            "user_team": "************",
            "editable": true,
            "size": 132,
            "mode": "snippet",
            "is_external": false,
            "external_type": "",
            "is_public": true,
            "public_url_shared": false,
            "display_as_bot": false,
            "username": "",
            "url_private": "https://files.slack.com/files-pri/*****************/testfile.txt",
            "url_private_download": "https://files.slack.com/files-pri/**************/download/testfile.txt",
            "permalink": "https://*******.slack.com/files/****************/testfile.txt",
            "permalink_public": "https://slack-files.com/********************",
            "edit_link": "https://************.slack.com/files/*************/*************/testfile.txt/edit",
            "preview": "Wed Dec 18 02:05:23 PM EET 2024 test line 1\nWed Dec 18 02:05:29 PM EET 2024 test line 2\nWed Dec 18 02:05:32 PM EET 2024 test line 3\n",
            "preview_highlight": "<div class=\"CodeMirror cm-s-default CodeMirrorServer\">\n<div class=\"CodeMirror-code\">\n<div><pre>Wed Dec 18 02:05:23 PM EET 2024 test line 1</pre></div>\n<div><pre>Wed Dec 18 02:05:29 PM EET 2024 test line 2</pre></div>\n<div><pre>Wed Dec 18 02:05:32 PM EET 2024 test line 3</pre></div>\n<div><pre></pre></div>\n</div>\n</div>\n",
            "lines": 4,
            "lines_more": 0,
            "preview_is_truncated": false,
            "comments_count": 0,
            "is_starred": false,
            "shares": {
                "public": {
                    "**************": [
                        {
                            "reply_users": [],
                            "reply_users_count": 0,
                            "reply_count": 0,
                            "ts": "1734524907.257849",
                            "channel_name": "*********",
                            "team_id": "********",
                            "share_user_id": "********",
                            "source": "UNKNOWN"
                        }
                    ]
                }
            },
            "channels": [
                "SLACK-CHANNEL-ID"
            ],
            "groups": [],
            "ims": [],
            "has_more_shares": false,
            "has_rich_preview": false,
            "file_access": "visible"
        }
    ]
}

With this method I can post files in specific channel.

I would strongly suggest to the devs to start planing and use this api since the old one will be deprecated in couple months.

Slack docs: https://api.slack.com/changelog/2024-04-a-better-way-to-upload-files-is-here-to-stay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant