A web application for deploying MediaWiki gadgets from git repos to Wikimedia wikis using OAuth with real-time streaming of deployment status.
- Access the application at https://gadget-deploy.toolforge.org
- Select a gadget from the available options (see below)
- Choose a target wiki from the available options
- Authenticate using OAuth
- Monitor the deployment in through the output logs streamed from Toolforge
Currently supported gadgets:
- Twinkle: https://github.com/wikimedia-gadgets/twinkle
- AfC Helper: https://github.com/wikimedia-gadgets/afc-helper
Steps to add a new gadget:
- Create deployment script for the gadget. Ideally, use node.js. It should read the API url of the wiki and an OAuth 2 access token from a JSON file and use them to do the deployment. Format of the credentials file generated by this tool is:
{
"site": "", // API url of the wiki, eg. https://en.wikipedia.org/w/api.php
"accessToken": "" // OAuth 2 access token
}Check afc-helper's deploy.js for an example. The script must not prompt for any user input.
- Raise a PR to add an entry in
gadget-conf.ts:
export const gadgetConfigurations = {
'new-gadget': {
name: 'New Gadget',
branch: 'main',
branchUrl: 'https://github.com/user/repo/commits/main',
instructions: [],
credentialsFilePath: 'scripts/credentials.json',
buildCommand: '', // Optional
deployCommand: 'npm run deploy',
wikis: ['testwiki', 'enwiki']
},
// ... existing gadgets
}- Clone the gadget's git repo on the Toolforge project:
ssh toolforge
become gadget-deploy
cd ~/www/js/repos
git clone https://github.com/user/gadget-123.git gadget-123 The key used in gadget-conf.ts should match the name of the cloned directory.
gadget-deploy/
├── client/ # React-based frontend for initiating deployments
├── server/ # Node.js backend using Express.js
├── repos/ # Gadget repositories (git-ignored)
│ ├── twinkle/
│ ├── afc-helper/
│ └── (other gadgets)
├── gadget-conf.ts # Gadget and wiki configurations
└── package.json # Root package.json
- Node.js 22+
- A local MediaWiki instance (for testing), with Extension:OAuth installed.
Install dependencies:
npm installCreate server/conf.ts by copying the template configuration file:
cp server/conf.template.ts server/conf.tsEdit it with your OAuth credentials and settings:
export default {
// REST API url of the central wiki (metawiki for Wikimedia cluster)
restApiUrl: 'http://localhost:4000/rest.php',
// The frontend url of the project (https://gadget-deploy.toolforge.org in production)
redirectUrl: 'http://localhost:3000',
// OAuth consumer credentials
clientId: 'your_oauth_client_id',
clientSecret: 'your_oauth_client_secret',
};To test locally, you'll need to register an OAuth consumer in your MediaWiki instance:
- Install OAuth extension in your MediaWiki instance
- Create a new OAuth consumer:
- Go to
Special:OAuthConsumerRegistration - Set redirect URL to:
http://localhost:3000 - Ignore the warning about redirect URL not having a path
- Note down the
client_idandclient_secret
- Go to
- Update your
server/conf.tswith the credentials
The deployment system expects gadget repositories in the repos/ directory:
cd repos
# Clone Twinkle (or any other gadget you want to deploy)
git clone https://github.com/wikimedia-gadgets/twinkle.gitYou could also just create a symlink to your local repository of the gadget.
# Build both client and server
npm run build
# Or build individually:
npm run build:client
npm run build:server# Start the server in development mode
cd server
npm run dev
# In another terminal, start the client
cd client
npm run devThe application will be available at:
- Frontend: http://localhost:3000
- Backend: http://localhost:3001
The PORT environment variable can be used to configure the ports on which client and server run. Backend API calls are also sent to the frontend URL. Vite proxies them to the backend (see configuration in vite.config.ts).
# Build the project first
npm run build
# Start the server
npm startIn production mode, the application will be available at http://localhost:3000. The client does not run separately. Instead, the build artefacts are served statically by the server.
-
OAuth authentication fails
- Verify your
client_idandclient_secretinserver/conf.ts - Ensure the callback URL matches your OAuth consumer registration
- Verify your
-
Deployment fails
- Check that the gadget repository exists in
repos/ - Check that gadget repository does not have any uncommitted changes
- Verify the gadget has the required deployment scripts
- Check the real-time logs in the web interface
- Check that the gadget repository exists in
-
Build errors
- Ensure all dependencies are installed
- Check TypeScript compilation errors
- Verify Node.js version compatibility
Server logs are available in the console where you started the server. The application uses Winston for structured logging.