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

Feature request: automated init & usage & fire-and-forget send, GitLab CI use-case #81

Closed
xurizaemon opened this issue Jun 17, 2022 · 34 comments
Labels
enhancement New feature or request solved The issue was solved or solution is known.

Comments

@xurizaemon
Copy link
Contributor

Hi there

Motivation / backstory

I'm interested to use this tool to send messages from Gitlab CI to our internal Matrix to report build success/failure.

Currently from the docs it appears to me that first run requires some interactive usage to configure home server. I see parameters for username and password but not home server.

(I see that the server is in the username, but from other Matrix clients I draw inference that these aren't always the same value.)

Once we have run interactive init it appears from docs we will be able to reuse the generated credentials.json until the token expires.

For this use case this would require interactive logins each week due to limited token lifetime on the target server. An automated login via password works on the target environment (tested with other clients) and is the solution I would like to implement with Matrix Commander.

Questions

Is it possible to automate (no interactive input) a username/password login? If so, am I missing documentation for a --homeserver or --init parameter? (#45 (comment))

I'm open to helping test or implement this, and happy to document usage of matrix-commander to send build/test notifications from Gitlab CI or GitHub Actions once I get it working.

@xurizaemon xurizaemon changed the title Document "one shot" usage automated init & usage Jun 17, 2022
@8go
Copy link
Owner

8go commented Jun 17, 2022

thanks @xurizaemon for your issue.

Just a quick first comment:

  • Do I understand correctly that you have an access token, or can generate an access token (without matrix-commander)? If so, you could just create the credentials file with a script. Then call matrix-commander for the first time with the credentials file already existing (produced externally by a script). Would that work for you?

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 17, 2022

Thanks. What I am looking for is a "one-shot" command to relay a message from CI to developer channel. At it's most minimal, the desired interface might be:

# Executed only when job failed:
matrix-commander \
  --server="${SERVER}" --username="${USERNAME}" --password="${PASSWORD}" \
  --room="${ROOM}" --message="CI job ${JOB} failed, see ${URL}"

I understand that Matrix auth workflow can use username/password to obtain a token and then use the token to relay messages. Generating the tokens separately will introduce an extra task, and if Matrix Commander is capable of rolling those two into a single step (as I am inferring, perhaps incorrectly), then it's fine (in my use case) for the access token to be used immediately and discarded.

I could create an access token - but I would rather not have to maintain access tokens per project if it's possible to hand that off to matrix-commander. (And I'm happy to help make that happen. For context, I'm using a similar approach in hubot-matrix, and login/password works well there, but matrix-commander looks like a better tool for command execution rather than leaving a bot running.)

@8go
Copy link
Owner

8go commented Jun 17, 2022

I think I understand what you @xurizaemon are suggesting. It is technically possible, I see no show-stopper.

Let me repeat and rephrase to see if I understand you correctly:

  • You have no other means of generating an access token? You have no access token?
  • This is a "throw-away" device, a use-only-once device? You execute mc once, that generates a new device and a new access token, and sends a message. But neither device nor access token will ever be used again.
  • How about verification and encryption? You are not using emoji verification? The device remains unverified and sends the message unverified?
  • After running mc and sending the one message, you wipe everything (store, credentials, etc).
  • Should clean-up be done? One could try to delete device after sending the one message. What other cleanup?
  • Are you using Synapse as Matrix server?
  • Are you using HTTPS on the Matrix server? If not, there are security implications.

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 18, 2022

  • Yes-ish 😄 Technically I do have a means of creating an access token, but it isn't suitable for this use case: the requirement needs long-lived credentials for automated use, in an environment with access tokens that expire after 1 week (which means access tokens become a maintenance task if handled directly).
  • Yes: This is a "throwaway" environment, where I pass environment variables (credentials, channel details) and the name of a container image (matrixcommander/matrix-commander) into a service which starts, reports the status of a test/build pipeline, and is destroyed.
  • SSO & emoji verification are not required nor suited for this automated use case. Security which might be provided via SSO or emoji verification is here addressed at other layers, in order to permit automated usage for cases like this.
  • Yes. (It's fine to create a credentials.json for one-shot usage, since it would be destroyed anyway, if that's a question for implementation.)
  • No cleanup is required (and while it might appear to suit this use case, other automated usage might not need that, so I'd keep the two separate.)
  • Yes
  • Yes 😄

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 18, 2022

Also: For some internal bots using the davidar/hubot-matrix adapter, I have e2e integration tests which make the bot pop up once a week on Monday and say "yep, everything still works". I'm doing this from Gitlab CI in the private environment, and it gives assurance that the tested Matrix adapter is compatible with the deployed Matrix/Synapse environment.

I'd be happy to contribute a similar scheduled demonstration (once it's possible with matrix-commander). I believe we can do that using the public matrix.org instance where there is a #test-bot:matrix.org channel used for that purpose. If you like that idea, that can be a follow-up issue. If you don't, no pressure - but maybe it's a useful contribution which could give a folks a working example of that "Github Actions (or Gitlab CI) to Matrix" use case?

@8go
Copy link
Owner

8go commented Jun 18, 2022

I am seeing 2 alternatives:

  • a throw-away alternative, like --ephemeral, you can use it only once,
  • a normal alternative, everything like today, but at init avoiding the user interaction, and taking the arguments from the command line instead. And the user can keep using the device, access-token for future operations or not.

These 2 alternatives are different.

  • How do you see them?
  • Where do you see more value for the mc community/users?
  • Which one is easier to explain to user? Does that matter?
  • I think both satisfy your needs, right?
  • Pros? Cons?
  • Which alternative do you like better and why?
  • Also, I am leaning towards using some sort of flag, something like --init or maybe --ephemeral. What would be the clearest way to present this to the user in your opinion? A flag? No flag? If you envision a flag, what would be a good name?

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 18, 2022

Without much insight (yet!) into the codebase, I'd say the normal alternative.

  • Introduce sufficient extra input parameters to gather the extra details (server is required, device name is optional and already defaults to "matrix-commander")
  • "normal" IMO option is equally valuable for community users (seems to be feature parity, and I would guess less effort to implement)
  • "normal" IMO is easier to explain as IMO it changes the behaviour of the program less but increases available functionality

I can see the use case for the --init flag if it's useful. It almost seems like might not be necessary; if we detect there are no saved credentials and that there are supplied credentials from parameters, it's fair to infer that the user expects init. If there are saved credentials discovered and a passed in --password then the availability of --init allows the user to specify that they want to create a fresh access token.

So I'd propose the new behaviour like this:

  • --server: Set the Matrix server to connect to.
  • --device-name: Set the device name on the Matrix server. If omitted, defaults to matrix-commander per current behaviour.
  • --init-creds: Authenticate (or re-authenticate) with the Matrix server, and store access token creds to the credentials store (-c parameter or its default). If no such file exists, this is set to true.

I believe the required inputs to be --server, --username, --password.

Optional inputs would be --main-room (can this be dropped, eg if we are using --listen?), --device-name (has a default).

I suggest --init-creds might describe the flag's usage more explicitly than just --init. This should also create the store directory and any other tasks required to ensure a working environment? The flag might also be useful for later expansion as a parameter (eg --init-creds=update might use details from credentials.json and a passed in password to generate a new token periodically). But that's for another story ;)

Hope these thoughts are useful - I need to stress that I haven't read the existing code!

@8go
Copy link
Owner

8go commented Jun 19, 2022

Thank you @xurizaemon for sharing your thoughts. I like hearing other people's opinion.

Hope these thoughts are useful

Yes they are.

I thought about it a bit. My current inclinations are:

  • add/use an option like --init, --initialize, --authenticate, --init-creds to explicitly create credentials. This is different than now. Now, it is implicit and without an argument. Reason: adding this argument makes it more clear, forces to user to decide; more obvious. This ambiguity leads to some rather long and winding warning messages. I started to dislike it. I think explicit init/authentication is better. The user decides and is conscious about it. Do you agree?
  • Based on extra arguments mc could dynamically decides if a) interactive (e.g. if no parameters given, so they need to be read from keyboard); or b) all info is given via arguments including a password, so it will be "batch" (like you are going to use it) as no further user queries are needed; c) if password is not given and --no-sso is not given then first try SSO, if SSO fails, then back to interactive.
  • I also thought about making the 3 sub-choices of --authentiticate (--init-creds or --init) explicit as well. E.g.
    • --authentiticate interactive (for a)
    • --authentiticate cli ... other args ... (for b) (your use case)
    • --authentiticate sso ... other args ... (for c)
    • The user must upfront think about and decide how he is going to authenticate and specify so via the sub-arguments like interactive, cli or sso.

Ok, you also brought up this issue: What to do if --authenticate etc is used and credentials already exist? Raise exception and stop? Let the user explicitly delete existing credentials beforehand if this is what he wants? Have your update as fourth options? But that raises the next question: User said update, but Update how? Via interactive, cli, sso? So, update not as a fourth option but as an extra flag giving a total of 6 choice: 3 options each with a) create new or b) update existing credentials.

So much regarding the user-facing CLI.

What is your opinion?

  • Top argument to make it explicit to the user that he wants to authenticate? I lean towards YES.
  • 2nd level argument to make it explicit HOW he wants to authenticate? I am not sure yet.
  • What about the update ? How to do that nicely?

Naming: No sure yet, I am not a big fan of --init-creds. 2 abbreviations. "creds" is also maybe not very clear to noobies, occasional users. --authenticate, --login, --sign-in, --sign-on, --kyc, --initialize, --setup? Matrix itself seems to use login. And there are: "m.login.password" "m.login.sso" and "m.login.token". Or https://matrix.org/docs/guides/client-server-api#login

So much regarding user facing CLI.

What is your opinion:

  • Top argument to make it explicit to the user that he wants to authenticate? I lean towards YES.
  • 2nd level argument to make it explicit HOW he wants to authenticate? I am not sure yet.

Internally the code needs to be restructured, authentication more/better separated from actions, etc. Arg checking needs to be modified, etc. It is not going to be a tiny change.

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 19, 2022

Yes, I support the decision to move to an explicit "login" action which creates the required configuration for usage.

Seems reasonable to then activate interactive requests in the case where not all details are required.

Making authenticate parameter arguments for interactive, sso, cli makes sense. Suggest password for cli as all usage is CLI, and for clarity given the Matrix protocol labels :)

I am not sure about update. However: if there's existing CLI support for testing if the credentials work, then the tool may already offer this "UNIX style" and might not need additional coding at all:

# Test existing creds and if no success, log in before proceeding.
(matrix-commander --joined-rooms &>/dev/null) || matrix-commander --login password --server $SERVER --username $USER --password $PASSWORD --room $ROOM
matrix-commander -m "Matrix commander is now logged in."

(untested example - if the credentials in JSON are expired, the --joined-rooms call will fail and trigger the --login call)

I think --login ([password|sso|interactive]) makes sense for labelling. I wondered if it needed to describe anything additional on the matrix-commander side of things.

  • "login" also means "create the credentials file at the default or -c supplied path", which is an internal detail that doesn't need additional signaling here.
  • Another detail which may occur is that matrix-commander may create a store directory (path can be configured using --store). Again this is an internal detail with default behaviour and a parameter for control, so no additional signaling required.

Based on my understanding of the matrix-commander details, it seems like --login is a clear label that doesn't omit anything.

@8go
Copy link
Owner

8go commented Jun 19, 2022

Let me rephrase to see if I understand your thoughts correctly @xurizaemon .

  • Yes, you are in favor of a required --login to explicitly signal authentication.
  • Yes, you are in favor of a second signal, e.g. [password|sso|interactive] to explicitly state HOW to log in.
  • You imply that Update could be implemented later or by the user by other means (e.g. your example check).

So far, I rephrase correctly?

2 follow-up questions:

  • password|sso|interactive is somewhat okay, but not perfect. Maybe we can label better. password and sso are good, but interactive does not quite fit the bill, because interactive is just a password via keyboard instead of command line argument. interactive is not quite in the same dimension as password and sso. What would be a better label for interactive ?
  • Or should the 3 options be: cli | web-browser | interactive as in authenticate via CLI, via interactive questions, or via browser (SSO) ? Those 3 terms would be in the same "dimension". What do you think about this alternative? Other ones you can think of? The text would then explain that for cli one needs to provide --password etc.
  • if update is delayed, then how should mc react if it finds credentials or a store? In my opinion it should raise exception and abort. mc should not overwrite credentials or store IMHO. Do you agree? Is there a better approach?

@8go
Copy link
Owner

8go commented Jun 19, 2022

I just looked at the code, currently SSO is also interactive, it gets some parameters (device name, etc) from keyboard, then the access token from the web-browser, but it is interactive. I now definitely dislike the password|sso|interactive triple because interactive can use password, and sso is interactive. This triple is way to confusing.

cli | web-browser | interactive is also not good. Because web-browser is just the token, but the other parameters could come from either cli or interactive. And interactive could be interpreted as interactive with password or interactive with SSO (web-browser).

I now revise my thoughts. Maybe it should be:

  • password | SSO as 1st dimension, explicitly to be chosen and set by the user
  • cli | interactive as 2nd dimension, implicitly done (?). If all arguments are set, then CLI. If info is missing, then request info via keyboard. If done implicitly than a sloppy programmer might miss one argument and then the batch script will hang forever because it is waiting for keyboard input. If cli | interactive were explicit, then mc could check if all arguments are provided and fail immediately if something is missing. So, I see some con and pros to cli | interactive being implicit or explicit.

What is your view on this?

--login would have a total of 4 (2x2) combinations. (Ignoring update)

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 19, 2022

It occurs to me that the labels "password" and "sso" make sense because they are the same type of thing: they describe the Matrix login interface. "interactive" (and "cli" and "web browser") describe a different type of thing: the matrix-commander / user-facing interface. The reason this feels confusing is that same commandline flag sometimes refers to one type and sometimes to another type of thing?

parameter documentation notes
--login-initialize, --get-access-token etc Perform initial authentication and credentials store. Label TBD. -c sets file to write to. Do we exit if the creds already exist? Does this fit better as --get-access-token (looking at other options that have verb-object structure)?
--login-method Only when --login-initialize. Currently password or sso.
--username Username. Already exists. What is current behaviour if credentials.json exists and user passes a different username?
--password When --login-method=password, the password. Already exists. Unclear if SSO or emoji could be automated?

So, for password login that needs to be fully automated:

matrix-commander -c $CREDS --login-initialize --login-method=password --server=$SERVER --username=$USER --password=$SECRET --room="$ROOM"
matrix-commander -m "I'm in!"

For SSO:

matrix-commander -c $CREDS --login-initialize --login-method=sso --server=$SERVER --username=$USER --room="$ROOM"
# > Interactive SSO presented.

(I don't think there's a situation where this needs an --sso-secret option?)

I expect that exposing 'cli' vs 'interactive' to users would be confusing because matrix-commander is an interactive CLI tool. Internally, this is a distinction: either we have to prompt for additional details (SSO secret, or omitted password), but that's determined by whether the details are provided by other options.

I'm enjoying this 😄 I hope I've answered your questions!

@8go
Copy link
Owner

8go commented Jun 20, 2022

Conceptually I agree to all. In the implementation details, my preferences vary slightly.

Follow up question, to clarify:

--get-access-token is meant as an alternative, as an alias, to --login-initialize ? Correct?

If so, then this is not a good choice IMHO, because I could envision (not implemented): 3 methods to --login. --login-method could be password, sso, or access-token. A user not-trusting mc could prefer giving mc an access-token instead of a password to perform login. In that sense --get-access-token would be confusing.

If an alias for --login or --login-initialize is desired, I would rather think of --authenticate.

BTW, emoji verify cannot be automated. Both SSO and amoji verify seem natively interactive to me.

--sso-secret : certainly not used today. I know nothing about it :)

I am glad you are enjoying this! 👏

@xurizaemon
Copy link
Contributor Author

Sure, yes. --get-access-token was an alternative name suggestion for --init ...

I wasn't sure if the existing CLI options followed the pattern noun-verb or verb-noun. Looking at the README I saw there are lots of --get-* options, so I followed that pattern with --get-access-token. --authenticate is fine.

@8go
Copy link
Owner

8go commented Jun 20, 2022

OK, understood.

I suggest the following then:

--login with being password or sso
(maybe --authenticate as alias for --login, but I think not to offer an alias. Simpler.)

In the future one might add access-token as a third alternative besides password or sso.

Whether it is "cli" or "interactive" will be done implicitly. If all info is provided thru command line then nothing needs to be queries from keyboard.

--username vs. --user : --user already exists, I am inclined to re-use --user

--homeserver : because this is the term I most frequently found in Matrix documentation. Also in Element Login screen, I think.

--password : already exists

--room : already exists

--device : not sure about that, --devices exists, easy to confuse. Ideas? Suggestions?

What do you think in general? Ways to improve it?

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 20, 2022

Agree, aliases not required, --login is fine. Likewise --user is fine, didn't intend to propose a new option there, just confusion here. --homeserver makes sense too.

Suggest --device-name to set the device identifier. NB: Matrix appears to let us re-use the existing / default which is actually a feature here, eg to prevent CI jobs creating many "devices". Default behaviour of --device-name=matrix-commander would not do that, but something like --device-name=mc-${GITLAB_CI_JOB} could get messy 😬

@8go
Copy link
Owner

8go commented Jun 21, 2022

We are 99% there I think.

--device-name : it seems ok, but it has a weak point. A minor inconsistency: We use --user and not --user-name or --user-id, we use --room and not --room_name or --room-id. Why would it be different with --device?

I also thought about renaming the existing --devices to --get-devices, but for the most part these labels have been chosen to be identical to the labels chosen by the nio API. In this case, the nio API uses devices().

That is the last uncertainty I have. I should look up what the Matrix documentation uses primarily. If they use mostly device-name that would speak for --device-name. Later today ...

@8go
Copy link
Owner

8go commented Jun 22, 2022

I looked at the Matrix documentation today. They use device and device-id. In the main document they never use device name. So, I think I stick with --device because that goes more in line with --room, --user, etc.

Maybe I add an alias --get-devices to --devices.

@8go
Copy link
Owner

8go commented Jun 24, 2022

See commit 9a08ecb

First draft of this --login. See also release 2.28.1 See release notes.

In the end I had to rename some flags, because I realized if I re-use flags like --room and --user then additional arguments to send or listen will be limited, restricted or awkward. In order to be able to --login, --verify, send, listen, get and set all in a single command, I found it better to create new labels like --user-login and --room-default. This way, --room-default can be used for --login while at the same time --room can be used for sending, etc.

Have a look @xurizaemon and test it out.

It should be able to do --login and --send (and much more) in a single command, all non-interactive.

Try something like:

matrix-commander --login password --user-login john --password "$PW" --homeserver example.net --device "" --room-default "someroom" -m "My message" --room jane

Note, while device name can be reused, devices will accumulate if you continuously perform new --login. Many device ids will share the same device name. But at one point it would be good to close all open devices. E.g. in Element in a simple operation, or with matrix-commander with the correct admin password. ...

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Jun 25, 2022

image

It works! (Gitlab CI job output here)

This is a CI job which builds the image from the repo's Dockerfile and then uses the built image and creds to post a message to the #test-bot:matrix.org channel.

As you say, devices accumulate for repeated --login instances, and they share the same device name.

This looks great! I will have a chance to test it more once I'm back at my desk next week 😁 Thanks!

@8go
Copy link
Owner

8go commented Jun 25, 2022

Hi @xurizaemon

Have a look at Commit be0a9a4 lines 124 and 125.

Feel free to create a PR to explain your use case better.

  • I do not mind at all if you say "user @xurizaemon ..."
  • Also, feel free to add a link to where people can see how it is done? How people can "clone" your use-case, etc.
  • No hurry. Whenever things are working fully for you, and you have documented it for yourself, etc. Then - if you like - add the appropriate use case description and necessary info/links to "copy"/"clone" your setup, ...

All voluntarily, share as much or as little as you feel comfortable.

8go pushed a commit that referenced this issue Jun 25, 2022
- all actions (login, verify, room, get, set, send, listen) can now be added at once to the command line and executed in one go
- cleanup of code
- removal of --no-sso
- as with last minor version, now --login is required explicitly and user must explicitly specify login method as "sso" or "password"
- see also Issue #81
@8go 8go added enhancement New feature or request solved The issue was solved or solution is known. labels Jun 25, 2022
@8go 8go changed the title automated init & usage Feature request: automated init & usage & fire-and-forget send Jun 25, 2022
@8go
Copy link
Owner

8go commented Jun 25, 2022

Regarding accumulating devices.

  • delete them periodically with matrix-commander script, can be automated.

  • delete them with Element, also quick and simple, but interactive

  • there is the following possibility:

    • create a new argument --device-id
    • have the user specify it at --login
    • mc passes it into AsyncClient() telling Matrix that we want to use this as device id.
    • after --login, after -m, do a --delete-device with --password (same for both I assume) and the a-priori known device-id
    • that means with a single mc command you create a device, log in, send msg, delete device. No accumulation of devices.
    • what I do not know is if matrix allows deletion of device from the currently active device. Since it is "in use" maybe it cannot be deleted.

This is just a possibility to explore. Would be "more complex" (2 more arguments in your command) but also "more clean" for your use case.

Thoughts?

@8go
Copy link
Owner

8go commented Jun 25, 2022

And there is another idea I have, that should be easy to do.

  • --logout to log out the current device from homeserver. This is actually what Element GUI/App does. Element IMHO does not delete the devices, it just logs them out. So, mc is then at the same level as Element in this specific issue. And I believe it reduces resource load on the server.

Once implemented (soon?) you should add this to your command.

I think this -logout is fully sufficient to avoid accumulating devices and to keep it nice, simple and clean. I think this is all you need.

@8go
Copy link
Owner

8go commented Jun 25, 2022

see commit 1218268
see release 3.0.1

implements --logout

Does this do everything now that you had in mind?

@xurizaemon
Copy link
Contributor Author

It does, I think! Great work, and thanks.

I thought the Gitlab CI example I linked to was visible, but I'd set the wrong visibility on that repo. It's visible now although there's more change in the MR than intended. Anyway, that was just for testing.

I'll try this out in a project this week and share a snippet for using Matrix Commander to signal results from Gitlab CI when I've got that going!

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Aug 11, 2022

Anyway, here's an example Gitlab CI config to send a notification after a failed job, and to create a failed job to trigger it for your testing. This configuration will fail every MR, and notify it to the channel configured via those $MATRIX_ environment variables (which you'd configure in your Gitlab's CI settings).

Ref: https://docs.gitlab.com/ee/ci/jobs/job_control.html

stages:
  - test
  - report

# Just here to trigger the report.
failing test:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  stage: test
  script:
    - echo "oh no it fail" && /bin/false

report to matrix:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  when: on_failure
  stage: report
  image: 
    name: matrixcommander/matrix-commander
    entrypoint: ["/bin/sh", "-c"]
  script:
    - export PATH=$PATH:/app/matrix_commander
    - matrix-commander --login password --user-login "${MATRIX_USERNAME}" --password "${MATRIX_PASSWORD}" --homeserver "${MATRIX_HOMESERVER}" --device "ci" --room-default "${MATRIX_ROOM}" -m "Pipeline ${CI_PROJECT_URL}/-/pipelines/${CI_PIPELINE_ID} for MR ${CI_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID} failed"

(This is just to document how you'd use the docker image to post notifications from Gitlab CI to Matrix - I'm not proposing the project moves from Github or anything, to be clear. We could do a similar thing with Github Actions here.)

@xurizaemon
Copy link
Contributor Author

I think this can be closed now - if you'd like the above contributed to docs, I'm happy to follow up with an additional PR?

@8go
Copy link
Owner

8go commented Oct 2, 2022

Excellent, thank you for sharing this GitLab CI example from your Gitlab CI use-case.
Examples always are helpful to other people.

I might add a link to this issue to the documentation. Thanks again @xurizaemon

@8go 8go changed the title Feature request: automated init & usage & fire-and-forget send Feature request: automated init & usage & fire-and-forget send, GitLab CI use-case Oct 2, 2022
@8go
Copy link
Owner

8go commented Oct 25, 2022

@xurizaemon

The fire-and-forget send is now also available on the Rust version, if for whatever reason this is preferable to you.

Check out:

@asmod3us
Copy link

I'm reading this thread with great interest and was wondering if the access token based auth mechanism was ever implemented? I'd like to send messages from CI without giving away the keys to the castle (account password).

@xurizaemon
Copy link
Contributor Author

@asmod3us if I recall right, using matrix-commander on CLI to login will produce an artifact of some kind which stores the token. There you go: credentials.json. Having generated such a file, you would be able to provide it as a variable in your CI environment (perhaps a "file variable", depending on CI platform), and have auth available.

Let us know how that turns out!

@asmod3us
Copy link

@xurizaemon thanks for the hint - there is indeed an access_token in credentials.json after logging in. I have also figured out how to create credentials.json with curl, so I can provide matrix-commander with one:

curl -q -s "https://${MATRIX_BASE_URL}/_matrix/client/v3/login" --data @- < <(jo -p \
	type=m.login.password \
	identifier="$(jo \
		type=m.id.user \
		user="${MATRIX_USERNAME}")" \
	password="${MATRIX_PASSWORD}" \
	device_id="${SERVICE}") |
jq 'del(.well_known)'

@xurizaemon
Copy link
Contributor Author

xurizaemon commented Sep 18, 2024

Just updating this issue with an updated .gitlab-ci.yml snippet for use with Matrix Commander.

Note that Gitlab now also has a built-in integration, which requires using token auth; Matrix Commander permits using username/password also.

Variables to configure in Gitlab CI/CD configuration are:

  • MATRIX_HOMESERVER
  • MATRIX_USERNAME
  • MATRIX_ROOM
  • MATRIX_PASSWORD
.notify matrix:
  stage: notify
  allow_failure: true
  image:
    name: matrixcommander/matrix-commander
    entrypoint: ["/bin/bash", "-l", "-c"]
  before_script:
    - export PATH=$PATH:/app/matrix_commander
    - matrix-commander --version
  script:
    - |+
      matrix-commander --login password \
        --user-login "${MATRIX_USERNAME}" \
        --password "${MATRIX_PASSWORD}" \
        --homeserver "${MATRIX_HOMESERVER}" \
        --room-default "${MATRIX_ROOM}" \
        --log-level ERROR ERROR \
        --device "ci" \
        -m "${NOTIFICATION_MESSAGE}"

success notification:
  extends: .notify matrix
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  variables:
    NOTIFICATION_MESSAGE: "🟢 ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}!${CI_MERGE_REQUEST_IID} pipeline passed\n- ${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID} - ${CI_PIPELINE_URL}"

failure notification:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: on_failure
  extends: .notify matrix
  variables:
    NOTIFICATION_MESSAGE: "⭕ ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}!${CI_MERGE_REQUEST_IID} pipeline failed\n- ${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID} - ${CI_PIPELINE_URL}"

The notify stage should follow other stages, so that the correct notify job fires when the pipeline has either succeeded or failed.

@8go
Copy link
Owner

8go commented Sep 22, 2024

Thank you @xurizaemon for this updat. This will be helpful to the community! 👏 👏 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request solved The issue was solved or solution is known.
Projects
None yet
Development

No branches or pull requests

3 participants